Imported Upstream version 2~rc2+svn403
authorDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sun, 8 Apr 2012 19:45:57 +0000 (22:45 +0300)
committerDimitrios Eftaxiopoulos <eftaxi12@otenet.gr>
Sun, 8 Apr 2012 19:45:57 +0000 (22:45 +0300)
43 files changed:
examples/full_test.cpp
include/mgl/base.h
include/mgl/canvas.h
include/mgl/canvas_cf.h
include/mgl/mgl.h
include/mgl/mgl_cf.h
include/mgl/qt.h
src/CMakeLists.txt
src/base.cpp
src/canvas.cpp
src/export.cpp
src/export_3d.cpp
src/pixel.cpp
src/plot.cpp
src/prc.cpp [new file with mode: 0644]
src/prc/PRC.h [new file with mode: 0644]
src/prc/PRCbitStream.cc [new file with mode: 0644]
src/prc/PRCbitStream.h [new file with mode: 0644]
src/prc/PRCdouble.cc [new file with mode: 0644]
src/prc/PRCdouble.h [new file with mode: 0644]
src/prc/oPRCFile.cc [new file with mode: 0644]
src/prc/oPRCFile.h [new file with mode: 0644]
src/prc/writePRC.cc [new file with mode: 0644]
src/prc/writePRC.h [new file with mode: 0644]
src/s_hull/COPYING.txt [new file with mode: 0644]
src/s_hull/s_hull.C [new file with mode: 0755]
src/s_hull/s_hull.h [new file with mode: 0644]
texinfo/core_en.texi
texinfo/core_ru.texi
texinfo/data_en.texi
texinfo/data_ru.texi
texinfo/example_en.texi
texinfo/example_ru.texi
texinfo/mathgl_ru.texi
texinfo/other_ru.texi
texinfo/parse_ru.texi
texinfo/toc_fr.html
texinfo/toc_ru.html
texinfo/web_fr.texi [new file with mode: 0644]
texinfo/web_ru.texi
todo.txt
widgets/fltk.cpp
widgets/qt.cpp

index b632fab9b87bcb39263abda3acfa16b938d72e00..04c79085341ce151b6ee6a50357783211e3e74a2 100644 (file)
@@ -49,31 +49,16 @@ void smgl_combined(mglGraph *gr);
 void save(mglGraph *gr,const char *name,const char *suf);\r
 void test(mglGraph *gr)\r
 {\r
-       float a=0.1,b=0.4,c=0.5;\r
-       gr->Line(mglPoint(a,1),mglPoint(b,1),"k-A");            gr->Puts(mglPoint(c,1),"Style 'A' or 'A\\_'",":rL");\r
-       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"k-V");        gr->Puts(mglPoint(c,0.8),"Style 'V' or 'V\\_'",":rL");\r
-       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"k-K");        gr->Puts(mglPoint(c,0.6),"Style 'K' or 'K\\_'",":rL");\r
-       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"k-I");        gr->Puts(mglPoint(c,0.4),"Style 'I' or 'I\\_'",":rL");\r
-       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"k-D");        gr->Puts(mglPoint(c,0.2),"Style 'D' or 'D\\_'",":rL");\r
-       gr->Line(mglPoint(a,0),mglPoint(b,0),"k-S");            gr->Puts(mglPoint(c,0),"Style 'S' or 'S\\_'",":rL");\r
-       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"k-O");      gr->Puts(mglPoint(c,-0.2),"Style 'O' or 'O\\_'",":rL");\r
-       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"k-T");      gr->Puts(mglPoint(c,-0.4),"Style 'T' or 'T\\_'",":rL");\r
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-_");      gr->Puts(mglPoint(c,-0.6),"Style '\\_' or none",":rL");\r
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-AS");     gr->Puts(mglPoint(c,-0.8),"Style 'AS'",":rL");\r
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-_A");         gr->Puts(mglPoint(c,-1),"Style '\\_A'",":rL");\r
-       \r
-       a=-1;   b=-0.7; c=-0.6;\r
-       gr->Line(mglPoint(a,1),mglPoint(b,1),"kAA");            gr->Puts(mglPoint(c,1),"Style 'AA'",":rL");\r
-       gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"kVV");        gr->Puts(mglPoint(c,0.8),"Style 'VV'",":rL");\r
-       gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"kKK");        gr->Puts(mglPoint(c,0.6),"Style 'KK'",":rL");\r
-       gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"kII");        gr->Puts(mglPoint(c,0.4),"Style 'II'",":rL");\r
-       gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"kDD");        gr->Puts(mglPoint(c,0.2),"Style 'DD'",":rL");\r
-       gr->Line(mglPoint(a,0),mglPoint(b,0),"kSS");            gr->Puts(mglPoint(c,0),"Style 'SS'",":rL");\r
-       gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"kOO");      gr->Puts(mglPoint(c,-0.2),"Style 'OO'",":rL");\r
-       gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"kTT");      gr->Puts(mglPoint(c,-0.4),"Style 'TT'",":rL");\r
-       gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-__");     gr->Puts(mglPoint(c,-0.6),"Style '\\_\\_'",":rL");\r
-       gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-VA");     gr->Puts(mglPoint(c,-0.8),"Style 'VA'",":rL");\r
-       gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AV");         gr->Puts(mglPoint(c,-1),"Style 'AV'",":rL");\r
+       mglData y;      mgls_prepare1d(&y);     gr->SetOrigin(0,0,0);\r
+       if(!mini)       {       gr->SubPlot(2,2,0,"");  gr->Title("Area plot (default)");       }\r
+       gr->Box();      gr->Area(y);\r
+       if(mini)        return;\r
+       gr->SubPlot(2,2,1,"");  gr->Title("2 colors");  gr->Box();      gr->Area(y,"cbgGyr");\r
+       gr->SubPlot(2,2,2,"");  gr->Title("'!' style"); gr->Box();      gr->Area(y,"!");\r
+       gr->SubPlot(2,2,3);     gr->Title("3d variant");        gr->Rotate(50,60);      gr->Box();\r
+       mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");\r
+       yc.Modify("sin(pi*(2*x-1))");   xc.Modify("cos(pi*2*x-pi)");\r
+       gr->Area(xc,yc,z,"r");\r
        return;\r
 \r
        mglParse par;\r
@@ -1886,12 +1871,15 @@ static struct option longopts[] =
        { "svg",                        no_argument,    &type,          2 },\r
        { "solid",                      no_argument,    &type,          3 },\r
        { "jpeg",                       no_argument,    &type,          4 },\r
-       { "idtf",                       no_argument,    &type,          5 },\r
+       { "prc",                        no_argument,    &type,          5 },\r
        { "gif",                        no_argument,    &type,          6 },\r
        { "none",                       no_argument,    &type,          7 },\r
        { "bps",                        no_argument,    &type,          8 },\r
        { "u3d",                        no_argument,    &type,          9 },\r
        { "pdf",                        no_argument,    &type,          10 },\r
+       { "obj",                        no_argument,    &type,          11 },\r
+       { "off",                        no_argument,    &type,          12 },\r
+       { "stl",                        no_argument,    &type,          13 },\r
        { "help",                       no_argument,    NULL,           '?' },\r
        { NULL,                         0,                              NULL,           0 }\r
 };\r
@@ -1911,6 +1899,9 @@ void usage()
                "-jpeg                  - output JPEG\n"\r
                "-solid                 - output solid PNG\n"\r
                "-svg                   - output SVG\n"\r
+               "-obj                   - output obj/mtl\n"\r
+               "-off                   - output off\n"\r
+               "-stl                   - output stl\n"\r
                "-none                  - none output\n"\r
                "-srnd                  - use the same random numbers in any run\n"\r
                "-kind=name             - produce only this picture"\r
@@ -1939,9 +1930,9 @@ void save(mglGraph *gr,const char *name,const char *suf="")
                case 4: // JPEG\r
                        sprintf(buf,"%s%s.jpg",name,suf);\r
                        gr->WriteJPEG(buf);     break;\r
-               case 5: // IDTF\r
-                       sprintf(buf,"%s%s.idtf",name,suf);\r
-                       gr->WriteIDTF(buf);     break;\r
+               case 5: // PRC\r
+                       sprintf(buf,"%s%s.prc",name,suf);\r
+                       gr->WritePRC(buf);      break;\r
                case 6: // GIF\r
                        sprintf(buf,"%s%s.gif",name,suf);\r
                        gr->WriteGIF(buf);      break;\r
@@ -1957,6 +1948,15 @@ void save(mglGraph *gr,const char *name,const char *suf="")
                case 10:        // PDF\r
                        sprintf(buf,"%s%s.pdf",name,suf);\r
                        //gr->WritePDF(buf);    break;  // TODO: Add IDTF support\r
+               case 11:        // OBJ\r
+                       sprintf(buf,"%s%s.obj",name,suf);\r
+                       gr->WriteOBJ(buf);      break;\r
+               case 12:        // OFF\r
+                       sprintf(buf,"%s%s.off",name,suf);\r
+                       gr->WriteOFF(buf);      break;\r
+               case 13:        // STL\r
+                       sprintf(buf,"%s%s.stl",name,suf);\r
+                       gr->WriteSTL(buf);      break;\r
                default:// PNG (no alpha)\r
                        sprintf(buf,"%s%s.png",name,suf);\r
                        gr->WritePNG(buf,0,false);      break;\r
index d7fb9f711a47af0251005c3a77185609b6291af2..c5d3de1a656895fd2750cc0214fbe30d45ce1af8 100644 (file)
@@ -112,7 +112,7 @@ struct mglPnt
        float c,t,ta;   // index in color scheme\r
        float u,v,w;    // normales\r
        float r,g,b,a;  // RGBA color\r
-       mglPnt()        {       xx=yy=zz=x=y=z=c=t=u=v=w=r=g=b=a=0;     }\r
+       mglPnt()        {       xx=yy=zz=x=y=z=c=t=ta=u=v=w=r=g=b=a=0;  }\r
 };\r
 inline mglPnt operator+(const mglPnt &a, const mglPnt &b)\r
 {      mglPnt c=a;\r
@@ -133,7 +133,7 @@ inline mglPnt operator*(float b, const mglPnt &a)
 //-----------------------------------------------------------------------------\r
 struct mglTexture\r
 {\r
-       mglColor col[514];      ///< Colors itself\r
+       mglColor col[512];      ///< Colors itself\r
        long n;                         ///< Number of initial colors along u\r
 \r
        char Sch[260];          ///< Color scheme used\r
@@ -146,7 +146,7 @@ struct mglTexture
        void Clear()    {       n=0;    }\r
        void Set(const char *cols, int smooth=0,float alpha=1);\r
        void GetC(float u,float v,mglPnt &p) const;\r
-       bool IsSame(mglTexture &t) const;\r
+       bool IsSame(const mglTexture &t) const;\r
        void GetRGBA(unsigned char *f) const;   // Write as BGRA for fastest export to TGA\r
 };\r
 //-----------------------------------------------------------------------------\r
index 165c8b4f66b4cb14e523d60f7fbc6da8d70155b8..6b15c6d27ad505f09b2872c2f337fcfd1654f5af 100644 (file)
@@ -124,7 +124,7 @@ using mglBase::Light;
        /// Zoom in or zoom out (if Zoom(0, 0, 1, 1)) a part of picture\r
        virtual void Zoom(float x1, float y1, float x2, float y2);\r
        /// Restore image after View() and Zoom()\r
-       virtual void Restore()  {       Bp.clear();     }\r
+       virtual void Restore()  {       Bp.clear();     Bp.pf=0;        }\r
 \r
        /// Clear transformation matrix.\r
        inline void Identity(bool rel=false)    {       InPlot(0,1,0,1,rel);    }\r
index a56aa6b61db1bb58d6684c4900bf2e39d1ebc9b6..8e80506081ab1c84a9c6276fb13c49149bfd4c22 100644 (file)
@@ -89,7 +89,7 @@ void mgl_write_off(HMGL gr, const char *fname,const char *descr, int colored);
 void mgl_write_xyz(HMGL gr, const char *fname,const char *descr);\r
 //void mgl_write_x3d(HMGL gr, const char *fname,const char *descr);\r
 void mgl_write_wgl(HMGL gr, const char *fname,const char *descr);\r
-void mgl_write_idtf(HMGL gr, const char *fname,const char *descr);\r
+void mgl_write_prc(HMGL gr, const char *fname,const char *descr, int make_pdf);\r
 void mgl_write_gif(HMGL gr, const char *fname,const char *descr);\r
 void mgl_start_gif(HMGL gr, const char *fname,int ms);\r
 void mgl_close_gif(HMGL graph);\r
@@ -193,7 +193,7 @@ void mgl_write_png_(uintptr_t *graph, const char *fname,const char *descr,int lf
 void mgl_write_png_solid_(uintptr_t *graph, const char *fname,const char *descr,int lf,int ld);\r
 void mgl_write_eps_(uintptr_t *graph, const char *fname,const char *descr,int lf,int ld);\r
 void mgl_write_svg_(uintptr_t *graph, const char *fname,const char *descr,int lf,int ld);\r
-void mgl_write_idtf_(uintptr_t *graph, const char *fname,const char *descr,int lf,int ld);\r
+void mgl_write_prc_(uintptr_t *graph, const char *fname,const char *descr, int *make_pdf,int lf,int ld);\r
 void mgl_write_gif_(uintptr_t *graph, const char *fname,const char *descr,int lf,int ld);\r
 void mgl_start_gif_(uintptr_t *graph, const char *fname,int *ms,int l);\r
 void mgl_close_gif_(uintptr_t *graph);\r
index 2bd12d3d5ec16d3a42b47715cb1757596060a92b..9546296253e5d18730ec3bf9f78e47f1c8edd314 100644 (file)
@@ -300,7 +300,7 @@ public:
        {       mgl_write_gif(gr, fname, descr);        }\r
 \r
        /// Write the frame in file using OBJ format\r
-       inline void WriteOBJ(const char *fname,const char *descr="",bool use_png=false)\r
+       inline void WriteOBJ(const char *fname,const char *descr="",bool use_png=true)\r
        {       mgl_write_obj(gr, fname, descr, use_png);       }\r
        /// Write the frame in file using XYZ format\r
        inline void WriteXYZ(const char *fname,const char *descr="")\r
@@ -314,9 +314,9 @@ public:
 //     /// Write the frame in file using X3D format\r
 //     inline void WriteX3D(const char *fname,const char *descr="")\r
 //     {       mgl_write_x3d(gr, fname, descr);        }\r
-       /// Write the frame in file using IDTF format\r
-       inline void WriteIDTF(const char *fname,const char *descr="")\r
-       {       mgl_write_idtf(gr, fname, descr);       }\r
+       /// Write the frame in file using PRC format\r
+       inline void WritePRC(const char *fname,const char *descr="",bool make_pdf=true)\r
+       {       mgl_write_prc(gr, fname, descr, make_pdf);      }\r
 \r
        /// Create new frame.\r
        inline void NewFrame()          {       mgl_new_frame(gr);      }\r
index 7f69feffda08650040bc48f5da6e8abb612b1082..98cf231163ae6ca616ed1d5a0ef7b9887bd5db48 100644 (file)
@@ -31,5 +31,6 @@
 #include "mgl/prim.h"\r
 #include "mgl/other.h"\r
 #include "mgl/canvas_cf.h"\r
+#include "mgl/addon.h"\r
 /*****************************************************************************/\r
 #endif\r
index e1f590de10b57d4fc5139f61e45a19c53755c1f2..08f7bcba3f719f2f6f4f6b37626f90c70136e0b6 100644 (file)
@@ -109,7 +109,7 @@ public slots:
        void exportSTL(QString fname="");       ///< export to STL file\r
        void exportOFF(QString fname="");       ///< export to OFF file\r
 //     void exportX3D(QString fname="");       ///< export to XYZ file\r
-       void exportIDTF(QString fname="");      ///< export to IDTF file\r
+       void exportPRC(QString fname="");       ///< export to PRC file\r
        void setMGLFont(QString path);          ///< restore/load font for graphics\r
 \r
        void adjust();          ///< Adjust plot size to fill entire window\r
index 294c5bb4671a6203552c1b0c28c2a3e714f18311..1dd1072dfdb479baa09fa44f1ea96b38ac8b073d 100644 (file)
@@ -16,6 +16,18 @@ set(mgl_hdr
 ../include/mgl/define.h                ../include/mgl/other.h  ../include/mgl/eval.h
 ../include/mgl/parser.h                ../include/mgl/addon.h  ../include/mgl/evalc.h )
 
+set(prc_src
+prc/PRCbitStream.cc prc/PRCdouble.cc prc/oPRCFile.cc prc/writePRC.cc prc.cpp
+)
+
+set(prc_hdr
+prc/PRC.h prc/PRCbitStream.h prc/PRCdouble.h prc/oPRCFile.h prc/writePRC.h
+)
+
+set(mgl_src ${mgl_src} ${prc_src} )
+set(mgl_hdr ${mgl_hdr} ${prc_hdr} )
+include_directories(prc)
+
 if(MGL_HAVE_OPENGL)
        set(mgl_src ${mgl_src} opengl.cpp )
        set(mgl_hdr ${mgl_hdr} ../include/mgl/opengl.h )
index 97b406dffd9b36c51bc02abbf056ba7783dae315..91309cccaecc1bfd17979ab9c78a36628b39ffc0 100644 (file)
@@ -125,16 +125,16 @@ long mglBase::AddPnt(mglPoint p, float c, mglPoint n, float a, int scl)
        if(get(MGL_REDUCEACC))\r
        {\r
                q.x=q.xx=int(p.x*10)*0.1;       q.y=q.yy=int(p.y*10)*0.1;       q.z=q.zz=int(p.z*10)*0.1;\r
-               q.c=int(c*100)*0.01;    q.t=int(a*100)*0.01;\r
+               q.c=int(c*100)*0.01;    q.t=q.ta=int(a*100)*0.01;\r
                q.u=int(n.x*100)*0.01;  q.v=int(n.y*100)*0.01;  q.w=int(n.z*100)*0.01;\r
        }\r
        else\r
        {\r
                q.x=q.xx=p.x;   q.y=q.yy=p.y;   q.z=q.zz=p.z;\r
-               q.c=c;  q.t=a;  q.u=n.x;        q.v=n.y;        q.w=n.z;\r
+               q.c=c;  q.t=q.ta=a;     q.u=n.x;        q.v=n.y;        q.w=n.z;\r
        }\r
-       q.x=q.xx=int(p.x*100)*0.01;     q.y=q.yy=p.y;   q.z=q.zz=p.z;\r
-       q.c=c;  q.t=q.ta=a;     q.u=n.x;        q.v=n.y;        q.w=n.z;\r
+//     q.x=q.xx=int(p.x*100)*0.01;     q.y=q.yy=p.y;   q.z=q.zz=p.z;\r
+//     q.c=c;  q.t=q.ta=a;     q.u=n.x;        q.v=n.y;        q.w=n.z;\r
        const mglTexture &txt=Txt[long(c)];\r
        txt.GetC(c,a,q);        // RGBA color\r
 \r
@@ -606,7 +606,7 @@ void mglTexture::Set(const char *s, int smooth, float alpha)
                {       c[1]=c[4];      c[3]=c[6];      n=2;    }\r
        }\r
        register float u,v=sm?(n-1)/255.:n/256.;\r
-       for(i=0;i<256;i++)\r
+       for(i=0;i<255;i++)\r
        {\r
                u = v*i;        j = long(u);    u-=j;\r
                if(!sm || j==n-1)\r
@@ -619,14 +619,14 @@ void mglTexture::Set(const char *s, int smooth, float alpha)
                        col[2*i+1]=c[2*j+1]*(1-u)+c[2*j+3]*u;\r
                }\r
        }\r
-       col[512]=col[510];      col[513]=col[511];\r
+       col[510]=col[508];      col[511]=col[509];\r
        delete []c;\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglTexture::GetC(float u,float v,mglPnt &p) const\r
 {\r
        u -= long(u);\r
-       register long i=long(256*u);    u = u*256-i;\r
+       register long i=long(255*u);    u = u*255-i;\r
        const mglColor *s=col+2*i;\r
        p.r = (s[0].r*(1-u)+s[2].r*u)*(1-v) + (s[1].r*(1-u)+s[3].r*u)*v;\r
        p.g = (s[0].g*(1-u)+s[2].g*u)*(1-v) + (s[1].g*(1-u)+s[3].g*u)*v;\r
@@ -634,7 +634,7 @@ void mglTexture::GetC(float u,float v,mglPnt &p) const
        p.a = (s[0].a*(1-u)+s[2].a*u)*v + (s[1].a*(1-u)+s[3].a*u)*(1-v);        // for alpha use inverted\r
 }\r
 //-----------------------------------------------------------------------------\r
-bool mglTexture::IsSame(mglTexture &t) const\r
+bool mglTexture::IsSame(const mglTexture &t) const\r
 {      return n==t.n && !memcmp(col,t.col,514*sizeof(mglColor));       }\r
 //-----------------------------------------------------------------------------\r
 long mglBase::AddTexture(const char *cols, int smooth)\r
@@ -653,9 +653,9 @@ float mglBase::AddTexture(mglColor c)
        register unsigned long i,j;\r
        if(!c.Valid())  return -1;\r
        // first lets try an existed one\r
-       for(i=0;i<Txt.size();i++)       for(j=0;j<256;j++)\r
+       for(i=0;i<Txt.size();i++)       for(j=0;j<255;j++)\r
                if(c==Txt[i].col[2*j])\r
-                       return i+j/256.;\r
+                       return i+j/255.;\r
        // add new texture\r
        mglTexture t;\r
        for(i=0;i<514;i++)      t.col[i]=c;\r
index 0960ee463520a2d4115b29a8dc79c376fe74f5fb..69f8a4699a488308421d3176ddfe2c1ce2ddd20e 100644 (file)
@@ -531,7 +531,7 @@ void mglCanvas::View(float tetx,float tetz,float tety)
 //-----------------------------------------------------------------------------\r
 void mglCanvas::Zoom(float x1, float y1, float x2, float y2)\r
 {\r
-       Bp.clear();             ClfZB();\r
+       Bp.pf=0;        Bp.clear();             ClfZB();\r
        if(x1==x2 || y1==y2)    {       x1=y1=0;        x2=y2=1;        }\r
        x1=2*x1-1;      x2=2*x2-1;      y1=2*y1-1;      y2=2*y2-1;\r
        Bp.b[0]=2/fabs(x2-x1);  Bp.b[4]=2/fabs(y2-y1);\r
@@ -777,7 +777,9 @@ void mglCanvas::StartAutoGroup (const char *lbl)
        static int id=1;\r
        if(lbl==NULL)   {       id=1;   return; }\r
        if(ObjId<0)     {       ObjId = -id;    id++;   }\r
-       MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);\r
+       register size_t len = Grp.size();\r
+       if(ObjId>=0 &&len>0 && ObjId!=Grp[len-1].Id)\r
+               MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);\r
 }\r
 //-----------------------------------------------------------------------------\r
 void mglCanvas::EndGroup()     {       LoadState();    }\r
index cf7262d093670bb14decc91fbbb5435c0fea89b4..3cfec52d768cfecf00c6e130210ce9b01feb5233 100644 (file)
@@ -467,7 +467,7 @@ void mgl_write_frame(HMGL gr, const char *fname,const char *descr)
        int len=strlen(fname);
        if(!strcmp(fname+len-4,".jpg")) mgl_write_jpg(gr,fname,descr);
        if(!strcmp(fname+len-5,".jpeg"))mgl_write_jpg(gr,fname,descr);
-       if(!strcmp(fname+len-5,".idtf"))mgl_write_idtf(gr,fname,descr);
+       if(!strcmp(fname+len-4,".prc")) mgl_write_prc(gr,fname,descr,1);
        if(!strcmp(fname+len-4,".png")) mgl_write_png(gr,fname,descr);
        if(!strcmp(fname+len-4,".eps")) mgl_write_eps(gr,fname,descr);
        if(!strcmp(fname+len-4,".svg")) mgl_write_svg(gr,fname,descr);
index 23dc428d02496377e4caa57eb71e39e011742255..84281f4c26e753bc680137a402291dfc8f2e848b 100644 (file)
@@ -233,7 +233,7 @@ void mgl_obj_prim(const mglPrim &q, const mglPnt &p, FILE *fp, float size)
                        fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n1,n1, n2,n2, n3,n3); break;\r
                case 3:\r
                        fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n1,n1, n2,n2, n3,n3);\r
-                       fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n4,n4, n2,n2, n3,n3); break;\r
+                       fprintf(fp,"f %ld/%ld %ld/%ld %ld/%ld\n", n2,n2, n4,n4, n3,n3); break;\r
                case 4: break;  // TODO: add glyphs export later\r
        }\r
 }\r
index 44530bb43fb489ebcd353f636cc73b3f74f73406..dedecde5857f4199054801cb8ace1767948d85e6 100644 (file)
@@ -385,6 +385,11 @@ void mglCanvas::Clf(mglColor Back)
        Fog(0);                 PDef = 0xffff;  pPos = 0;       StartAutoGroup(NULL);\r
        Pnt.clear();    Prm.clear();    Ptx.clear();\r
        Sub.clear();    Leg.clear();    Grp.clear();\r
+\r
+       Txt.clear();    Txt.reserve(3);\r
+       Txt.push_back(mglTexture(MGL_DEF_PAL,-1));\r
+       Txt.push_back(mglTexture("BbcyrR",1));\r
+       \r
        if(Back==0)                     Back = 'w';\r
        if((Flag&3)==2) Back = 'k';\r
        BDef[0]=Back.r*255;     BDef[1]=Back.g*255;BDef[2]=Back.b*255;  BDef[3]=0;\r
index e9cae29f997c8296dcb9074d0ab514aa8401d786..30897787a8982a6d5d93ee9553935a633d9a1f47 100644 (file)
@@ -474,9 +474,7 @@ void mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *
        for(j=0;j<m;j++)\r
        {\r
                c2=c1=gr->NextColor(pal);\r
-               if(gr->GetNumPal(pal)==2*m && !sh)\r
-               {       c1 = s+2*j/(2*m-1.);    c2 = s+(2*j+0.999)/(2*m-1);     }\r
-//             if(gr->GetNumPal(pal)==2*m)     c2 = gr->NextColor(pal);\r
+               if(gr->GetNumPal(pal)==2*m && !sh)      c2 = gr->NextColor(pal);\r
                mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;        mz = j<z->GetNy() ? j:0;\r
 \r
                nn = mglPoint(-y->dvx(0,my),x->dvx(0,mx));\r
@@ -520,8 +518,7 @@ void mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)
        for(j=0;j<m;j++)\r
        {\r
                c2=c1=gr->NextColor(pal);\r
-               if(gr->GetNumPal(pal)==2*m && !sh)\r
-               {       c1 = s+2*j/(2*m-1.);    c2 = s+(2*j+0.999)/(2*m-1);     }\r
+               if(gr->GetNumPal(pal)==2*m && !sh)      c2=gr->NextColor(pal);\r
                mx = j<x->GetNy() ? j:0;        my = j<y->GetNy() ? j:0;\r
                z0 = gr->Min.z + (m-1-j)*(gr->Max.z-gr->Min.z)/m;\r
 \r
@@ -593,8 +590,7 @@ void mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen, const cha
        for(j=0;j<m;j++)\r
        {\r
                c2=c1=gr->NextColor(pal);\r
-               if(gr->GetNumPal(pal)==2*m && !sh)\r
-               {       c1 = s+2*j/(2*m-1.);    c2 = s+(2*j+0.999)/(2*m-1);     }\r
+               if(gr->GetNumPal(pal)==2*m && !sh)      c2=gr->NextColor(pal);\r
                mx = j<x->GetNy() ? j:0;\r
                float z0 = gr->Min.z + (m-1-j)*(gr->Max.z-gr->Min.z)/m;\r
 \r
diff --git a/src/prc.cpp b/src/prc.cpp
new file mode 100644 (file)
index 0000000..4e93b10
--- /dev/null
@@ -0,0 +1,818 @@
+/***************************************************************************\r
+ * export_3d.cpp is part of Math Graphic Library\r
+ * Copyright (C) 2007 Alexey Balakin <balakin@appl.sci-nnov.ru>            *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU Library General Public License as       *\r
+ *   published by the Free Software Foundation; either version 3 of the    *\r
+ *   License, or (at your option) any later version.                       *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU Library General Public     *\r
+ *   License along with this program; if not, write to the                 *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#include <stdio.h>\r
+#include <time.h>\r
+#include <zlib.h>\r
+#include "mgl/canvas.h"\r
+#include "mgl/canvas_cf.h"\r
+\r
+#include "oPRCFile.h"\r
+#include <map>\r
+#include <utility>\r
+#include <string.h>\r
+#include <iostream>\r
+#include <iomanip>\r
+#include <fstream>\r
+#include <png.h>\r
+\r
+#if MGL_HAVE_PDF\r
+#include <stdlib.h>\r
+#include <setjmp.h>\r
+#include <math.h>\r
+#include <hpdf.h>\r
+#include <hpdf_u3d.h>\r
+#include <hpdf_annotation.h>\r
+#endif // MGL_HAVE_PDF\r
+\r
+\r
+#undef _GR_\r
+#define _GR_   ((mglCanvas *)(*gr))\r
+#define _Gr_   ((mglCanvas *)(gr))\r
+int mgl_tga_save(const char *fname, int w, int h, unsigned char **p);\r
+int mgl_pnga_save(const char *fname, int w, int h, unsigned char **p);\r
+void mgl_printf(void *fp, bool gz, const char *str, ...);\r
+//-----------------------------------------------------------------------------\r
+struct prctriangle {\r
+       uint32_t pi[3];\r
+       uint32_t ti[3];\r
+};\r
+//-----------------------------------------------------------------------------\r
+struct prctriangles {\r
+       prctriangles(const HMGL g) : samecolour(true), colourset(false),\r
+       gr(g), ntxt(g->GetTxtNum()) {}\r
+       std::map<PRCVector3d,uint32_t> points;\r
+       std::map<PRCVector2d,uint32_t> texturecoords;\r
+       std::vector<prctriangle> triangles;\r
+       RGBAColour colour;\r
+       bool samecolour;\r
+       bool colourset;\r
+       const HMGL gr;\r
+       const size_t ntxt;\r
+       \r
+       \r
+       uint32_t addPoint(const mglPnt& p)\r
+       {\r
+               const PRCVector3d point(p.x,p.y,p.z);\r
+               \r
+               std::map<PRCVector3d,uint32_t>::iterator pPoint = points.find(point);\r
+               if(pPoint!=points.end())\r
+                       return pPoint->second;\r
+               else\r
+               {\r
+                       const uint32_t point_index = points.size();\r
+                       points.insert(std::make_pair(point,point_index));\r
+                       return point_index;\r
+               }\r
+       }\r
+       \r
+       uint32_t addPoint(float x, float y, float z)\r
+       {\r
+               const PRCVector3d point(x,y,z);\r
+               \r
+               std::map<PRCVector3d,uint32_t>::iterator pPoint = points.find(point);\r
+               if(pPoint!=points.end())\r
+                       return pPoint->second;\r
+               else\r
+               {\r
+                       const uint32_t point_index = points.size();\r
+                       points.insert(std::make_pair(point,point_index));\r
+                       return point_index;\r
+               }\r
+       }\r
+       \r
+       void writePoints(double (*P)[3])\r
+       {\r
+               for(std::map<PRCVector3d,uint32_t>::const_iterator pPoint = points.begin(); pPoint != points.end(); pPoint++)\r
+               {\r
+                       P[pPoint->second][0] = pPoint->first.x;\r
+                       P[pPoint->second][1] = pPoint->first.y;\r
+                       P[pPoint->second][2] = pPoint->first.z;\r
+               }\r
+       }\r
+       \r
+       uint32_t addTextureCoords(const mglPnt& p)\r
+       {\r
+               const float u = ((1-p.ta)*(512-2)+1)/512;\r
+               const float v = ((1-p.c/ntxt)*(512*ntxt-2) + 1)/(512*ntxt);\r
+               \r
+               const PRCVector2d point(u, v);\r
+               \r
+               if (colourset) {\r
+                       if (samecolour) {\r
+                               if (colour.R != p.r || colour.G != p.g || colour.B != p.b || colour.A != p.a)\r
+                                       samecolour = false;\r
+                       }\r
+               }\r
+               else {\r
+                       colour.Set(p.r, p.g, p.b, p.a);\r
+                       colourset = true;\r
+               }\r
+               \r
+               \r
+               std::map<PRCVector2d,uint32_t>::iterator pPoint = texturecoords.find(point);\r
+               if(pPoint!=texturecoords.end())\r
+                       return pPoint->second;\r
+               else\r
+               {\r
+                       const uint32_t point_index = texturecoords.size();\r
+                       texturecoords.insert(std::make_pair(point,point_index));\r
+                       return point_index;\r
+               }\r
+       }\r
+       \r
+       void writeTextureCoords(double (*P)[2])\r
+       {\r
+               for(std::map<PRCVector2d,uint32_t>::const_iterator pPoint = texturecoords.begin(); pPoint != texturecoords.end(); pPoint++)\r
+               {\r
+                       P[pPoint->second][0] = pPoint->first.x;\r
+                       P[pPoint->second][1] = pPoint->first.y;\r
+               }\r
+       }\r
+};\r
+//-----------------------------------------------------------------------------\r
+/* structure to store PNG image bytes */\r
+struct png_buf\r
+{\r
+       uint8_t *data;\r
+       size_t size;\r
+};\r
+//-----------------------------------------------------------------------------\r
+void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)\r
+{\r
+       struct png_buf* p=(struct png_buf*)png_get_io_ptr(png_ptr);\r
+       size_t nsize = p->size + length;\r
+       \r
+       /* allocate or grow buffer */\r
+       if(p->data)\r
+               p->data = (uint8_t*)realloc(p->data, nsize);\r
+       else\r
+               p->data = (uint8_t*)malloc(nsize);\r
+       \r
+       if(!p->data)\r
+               png_error(png_ptr, "Write Error - no mem");\r
+       \r
+       /* copy new bytes to end of buffer */\r
+       memcpy(p->data + p->size, data, length);\r
+       p->size += length;\r
+}\r
+//-----------------------------------------------------------------------------\r
+void my_png_flush(png_structp png_ptr)\r
+{\r
+}\r
+//-----------------------------------------------------------------------------\r
+void mgl_write_prc(HMGL gr, const char *fname,const char *descr, int make_pdf)\r
+{\r
+       if(gr->GetPrmNum()<=0)  return; // nothing to do\r
+//     register size_t i,j;\r
+       {\r
+               long m1=0,m2=0,m;\r
+               for(size_t i=0;i<gr->Grp.size();i++)    // prepare array of indirect indexing\r
+               {       m = gr->Grp[i].Id;      if(m<m1) m1=m;  if(m>m2) m2=m;  }\r
+               long *ng = new long[m2-m1+1];\r
+               for(size_t i=0;i<gr->Grp.size();i++)    ng[gr->Grp[i].Id-m1] = i;\r
+               for(size_t i=0;i<size_t(gr->GetPrmNum());i++)   // collect data for groups\r
+               // it is rather expensive (extra 4b per primitive) but need for export to 3D\r
+               {\r
+                       m = gr->GetPrm(i).id-m1;\r
+                       if(m>=0 && m<m2-m1+1)   gr->Grp[ng[m]].p.push_back(i);\r
+               }\r
+               delete []ng;\r
+       }\r
+       const unsigned len=strlen(fname);\r
+       char * const tname = new char[len+9];   strcpy(tname,fname);\r
+       if (strncmp(tname+len-4, ".prc", 4)!=0)\r
+       {\r
+               tname[len]='.'; tname[len+1]='p';       tname[len+2]='r';       tname[len+3]='c'; tname[len+4]='\0';\r
+       }\r
+       oPRCFile file(tname);\r
+       PRCoptions grpopt;\r
+       grpopt.tess = true;\r
+       grpopt.closed = false; // set to true to make only front side visible\r
+       //      grpopt.no_break = true;\r
+       //      grpopt.do_break = false;\r
+\r
+       uint32_t materialMathGLid = m1;\r
+       {\r
+               png_buf buffer;\r
+               buffer.data = (uint8_t*)malloc(1024);;\r
+               buffer.size = 0;\r
+               const size_t ntxt = gr->GetTxtNum();\r
+\r
+               // prepare texture file (PNG)\r
+               const png_uint_32 width=256, height=256*ntxt;\r
+               png_bytep buf = new png_byte[4*width*height];\r
+               png_bytepp pbuf= new png_bytep[height];\r
+               for(size_t i=0;i<height;i++)    pbuf[i] = buf+4*width*i;\r
+               for(size_t i=0;i<ntxt;i++)      gr->GetTxt(i).GetRGBA(buf+i*256*256*4);\r
+\r
+               png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);\r
+               png_infop info_ptr = png_create_info_struct(png_ptr);\r
+\r
+               png_set_write_fn(png_ptr, &buffer, my_png_write_data, my_png_flush);\r
+               png_set_filter(png_ptr, 0, PNG_ALL_FILTERS);\r
+               png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);\r
+               png_set_IHDR(png_ptr, info_ptr, width, height, 8,\r
+                                       PNG_COLOR_TYPE_RGB_ALPHA,\r
+                               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,\r
+                               PNG_FILTER_TYPE_DEFAULT);\r
+               png_set_rows(png_ptr, info_ptr, pbuf);\r
+               png_write_png(png_ptr, info_ptr,        PNG_TRANSFORM_IDENTITY, 0);\r
+               png_write_end(png_ptr, info_ptr);\r
+\r
+               png_destroy_write_struct(&png_ptr, &info_ptr);\r
+               delete []pbuf;  delete []buf;\r
+               const PRCmaterial materialMathGL(\r
+                       RGBAColour(0.1,0.1,0.1,1), // ambient\r
+                       RGBAColour(1.0,1.0,1.0,1), // diffuse\r
+                       RGBAColour(0.1,0.1,0.1,1), //emissive\r
+                       RGBAColour(0.0,0.0,0.0,1), //spectral\r
+                       1.0,0.1, // alpha, shininess\r
+                       buffer.data, KEPRCPicture_PNG, 0, 0, buffer.size, true);\r
+               materialMathGLid = file.addMaterial(materialMathGL);\r
+               free(buffer.data); buffer.data = NULL;\r
+       }\r
+\r
+       // primitive definition in groups\r
+\r
+       mglPnt p0;\r
+       p0.x = dynamic_cast<mglCanvas *>(gr)->GetWidth()/2.;\r
+       p0.y = dynamic_cast<mglCanvas *>(gr)->GetHeight()/2.;\r
+       p0.z = sqrt(p0.x*p0.y);\r
+\r
+       for(size_t i=0;i<gr->Grp.size();i++)\r
+       {\r
+               const   std::vector<long>& p = gr->Grp[i].p;\r
+               prctriangles group(gr);\r
+               file.begingroup(gr->Grp[i].Lbl.c_str(),&grpopt);\r
+               for(size_t j=0;j<p.size();j++)\r
+               {\r
+                       const mglPrim &q=gr->GetPrm(p[j]);\r
+                       const double w = (q.w>1)?(q.w*sqrt(gr->FontFactor()/400.)):1;\r
+\r
+                       const mglPnt p = gr->GetPnt(q.n1) - p0;\r
+                       const float size = q.s*gr->FontFactor();\r
+                       {\r
+                               char type = q.n4;       float ss=size*0.35;\r
+                               const RGBAColour c(p.r, p.g, p.b, p.a);\r
+                               switch(q.type)\r
+                               {\r
+                                       case 0:\r
+                                               if(!strchr("xsSoO",type))       ss *= 1.1;\r
+                                               if(type=='.' || ss==0)\r
+                                               {\r
+                                                       const double P[3] = {p.x, p.y, p.z};\r
+                                                       file.addPoint(P, c, w);\r
+                                               }\r
+                                               else\r
+                                                       switch(type)\r
+                                                       {\r
+                                                               case 'P':\r
+                                                               {\r
+                                                                       const double P[5][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y-ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(5, P, c, w);\r
+                                                               }\r
+                                                               case '+':\r
+                                                               {\r
+                                                                       const double P1[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y,p.z },\r
+                                                                               { p.x+ss,p.y,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P1, c, w);\r
+                                                                       const double P2[2][3] =\r
+                                                                       {\r
+                                                                               { p.x,p.y-ss,p.z },\r
+                                                                               { p.x,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P2, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'X':\r
+                                                               {\r
+                                                                       const double P[5][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y-ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(5, P, c, w);\r
+                                                                       const double P1[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P1, c, w);\r
+                                                                       const double P2[2][3] =\r
+                                                                       {\r
+                                                                               { p.x+ss,p.y-ss,p.z },\r
+                                                                               { p.x-ss,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P2, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'x':\r
+                                                               {\r
+                                                                       const double P1[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P1, c, w);\r
+                                                                       const double P2[2][3] =\r
+                                                                       {\r
+                                                                               { p.x+ss,p.y-ss,p.z },\r
+                                                                               { p.x-ss,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P2, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'S':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x-ss,p.y-ss,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x+ss,p.y-ss,p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x-ss,p.y+ss,p.z);\r
+                                                                       const uint32_t pi4 = group.addPoint(p.x+ss,p.y+ss,p.z);\r
+\r
+                                                                       prctriangle triangle1, triangle2;\r
+                                                                       triangle1.pi[0] = pi1;\r
+                                                                       triangle1.pi[1] = pi2;\r
+                                                                       triangle1.pi[2] = pi3;\r
+                                                                       triangle1.ti[0] = ti;\r
+                                                                       triangle1.ti[1] = ti;\r
+                                                                       triangle1.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle1);\r
+                                                                       triangle2.pi[0] = pi4;\r
+                                                                       triangle2.pi[1] = pi3;\r
+                                                                       triangle2.pi[2] = pi2;\r
+                                                                       triangle2.ti[0] = ti;\r
+                                                                       triangle2.ti[1] = ti;\r
+                                                                       triangle2.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle2);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 's':\r
+                                                               {\r
+                                                                       const double P[5][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y-ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(5, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'D':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x,p.y-ss,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x+ss,p.y,p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x-ss,p.y,p.z);\r
+                                                                       const uint32_t pi4 = group.addPoint(p.x,p.y+ss,p.z);\r
+\r
+                                                                       prctriangle triangle1, triangle2;\r
+                                                                       triangle1.pi[0] = pi1;\r
+                                                                       triangle1.pi[1] = pi2;\r
+                                                                       triangle1.pi[2] = pi3;\r
+                                                                       triangle1.ti[0] = ti;\r
+                                                                       triangle1.ti[1] = ti;\r
+                                                                       triangle1.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle1);\r
+                                                                       triangle2.pi[0] = pi4;\r
+                                                                       triangle2.pi[1] = pi3;\r
+                                                                       triangle2.pi[2] = pi2;\r
+                                                                       triangle2.ti[0] = ti;\r
+                                                                       triangle2.ti[1] = ti;\r
+                                                                       triangle2.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle2);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'd':\r
+                                                               {\r
+                                                                       const double P[5][3] =\r
+                                                                       {\r
+                                                                               { p.x,p.y-ss,p.z },\r
+                                                                               { p.x+ss,p.y,p.z },\r
+                                                                               { p.x,p.y+ss,p.z },\r
+                                                                               { p.x-ss,p.y,p.z },\r
+                                                                               { p.x,p.y-ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(5, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'Y':\r
+                                                               {\r
+                                                                       const double P1[3][3] =\r
+                                                                       {\r
+                                                                               { p.x,                   p.y-ss,                p.z },\r
+                                                                               { p.x,                   p.y,                    p.z },\r
+                                                                               { p.x+0.8*ss,p.y+0.6*ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(3, P1, c, w);\r
+                                                                       const double P2[2][3] =\r
+                                                                       {\r
+                                                                               { p.x,                   p.y,                    p.z },\r
+                                                                               { p.x-0.8*ss,p.y+0.6*ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P2, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case '*':\r
+                                                               {\r
+                                                                       const double P1[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y,p.z },\r
+                                                                               { p.x+ss,p.y,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P1, c, w);\r
+                                                                       const double P2[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-0.6*ss,p.y-0.8*ss,p.z },\r
+                                                                               { p.x+0.6*ss,p.y+0.8*ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P2, c, w);\r
+                                                                       const double P3[2][3] =\r
+                                                                       {\r
+                                                                               { p.x-0.6*ss,p.y+0.8*ss,p.z },\r
+                                                                               { p.x+0.6*ss,p.y-0.8*ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(2, P3, c, w);\r
+\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'T':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x-ss,p.y-ss/2,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x+ss,p.y-ss/2,p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x,p.y+ss,p.z);\r
+\r
+                                                                       prctriangle triangle;\r
+                                                                       triangle.pi[0] = pi1;\r
+                                                                       triangle.pi[1] = pi2;\r
+                                                                       triangle.pi[2] = pi3;\r
+                                                                       triangle.ti[0] = ti;\r
+                                                                       triangle.ti[1] = ti;\r
+                                                                       triangle.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle);\r
+                                                               }\r
+                                                               break;\r
+                                                               case '^':\r
+                                                               {\r
+                                                                       const double P[4][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y-ss/2,p.z },\r
+                                                                               { p.x+ss,p.y-ss/2,p.z },\r
+                                                                               { p.x,   p.y+ss,        p.z },\r
+                                                                               { p.x-ss,p.y-ss/2,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(4, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'V':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x-ss,p.y+ss/2,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x,p.y-ss,p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x+ss,p.y+ss/2,p.z);\r
+\r
+                                                                       prctriangle triangle;\r
+                                                                       triangle.pi[0] = pi1;\r
+                                                                       triangle.pi[1] = pi2;\r
+                                                                       triangle.pi[2] = pi3;\r
+                                                                       triangle.ti[0] = ti;\r
+                                                                       triangle.ti[1] = ti;\r
+                                                                       triangle.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'v':\r
+                                                               {\r
+                                                                       const double P[4][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss,p.y+ss/2,p.z },\r
+                                                                               { p.x+ss,p.y+ss/2,p.z },\r
+                                                                               { p.x,   p.y-ss,        p.z },\r
+                                                                               { p.x-ss,p.y+ss/2,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(4, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'L':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x+ss/2,p.y+ss,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x-ss,     p.y,     p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x+ss/2,p.y-ss,p.z);\r
+\r
+                                                                       prctriangle triangle;\r
+                                                                       triangle.pi[0] = pi1;\r
+                                                                       triangle.pi[1] = pi2;\r
+                                                                       triangle.pi[2] = pi3;\r
+                                                                       triangle.ti[0] = ti;\r
+                                                                       triangle.ti[1] = ti;\r
+                                                                       triangle.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle);\r
+                                                               }\r
+                                                               break;\r
+                                                               case '<':\r
+                                                               {\r
+                                                                       const double P[4][3] =\r
+                                                                       {\r
+                                                                               { p.x+ss/2,p.y+ss,p.z },\r
+                                                                               { p.x+ss/2,p.y-ss,p.z },\r
+                                                                               { p.x-ss,       p.y,     p.z },\r
+                                                                               { p.x+ss/2,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(4, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'R':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t pi1 = group.addPoint(p.x-ss/2,p.y+ss,p.z);\r
+                                                                       const uint32_t pi2 = group.addPoint(p.x-ss/2,p.y-ss,p.z);\r
+                                                                       const uint32_t pi3 = group.addPoint(p.x+ss,     p.y,     p.z);\r
+\r
+                                                                       prctriangle triangle;\r
+                                                                       triangle.pi[0] = pi1;\r
+                                                                       triangle.pi[1] = pi2;\r
+                                                                       triangle.pi[2] = pi3;\r
+                                                                       triangle.ti[0] = ti;\r
+                                                                       triangle.ti[1] = ti;\r
+                                                                       triangle.ti[2] = ti;\r
+                                                                       group.triangles.push_back(triangle);\r
+                                                               }\r
+                                                               break;\r
+                                                               case '>':\r
+                                                               {\r
+                                                                       const double P[4][3] =\r
+                                                                       {\r
+                                                                               { p.x-ss/2,p.y+ss,p.z },\r
+                                                                               { p.x-ss/2,p.y-ss,p.z },\r
+                                                                               { p.x+ss,       p.y,     p.z },\r
+                                                                               { p.x-ss/2,p.y+ss,p.z }\r
+                                                                       };\r
+                                                                       file.addLine(4, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'O':\r
+                                                               {\r
+                                                                       const uint32_t ti = group.addTextureCoords(p);\r
+\r
+                                                                       const uint32_t cpi=group.addPoint(p);\r
+                                                                       uint32_t pi[21];\r
+                                                                       for(size_t j=0;j<=20;j++)\r
+                                                                               pi[j]=group.addPoint(p.x+ss*cos(j*M_PI/10),p.y+ss*sin(j*M_PI/10),p.z);\r
+                                                                       for(size_t j=0;j<=20;j++) {\r
+                                                                               prctriangle triangle;\r
+                                                                               triangle.pi[0] = pi[j];\r
+                                                                               triangle.pi[1] = pi[j+1];\r
+                                                                               triangle.pi[2] = cpi;\r
+                                                                               triangle.ti[0] = ti;\r
+                                                                               triangle.ti[1] = ti;\r
+                                                                               triangle.ti[2] = ti;\r
+                                                                               group.triangles.push_back(triangle);\r
+                                                                       }\r
+                                                               }\r
+                                                               break;\r
+                                                               case 'C':\r
+                                                               {\r
+                                                                       const double P[3] = {p.x, p.y, p.z};\r
+                                                                       file.addPoint(P, c, w);\r
+                                                               }\r
+                                                               case 'o':\r
+                                                               {\r
+                                                                       double P[21][3];\r
+                                                                       for(size_t j=0;j<=20;j++) {\r
+                                                                               P[j][0] = p.x+ss*cos(j*M_PI/10);\r
+                                                                               P[j][1] = p.y+ss*sin(j*M_PI/10);\r
+                                                                               P[j][2] = p.z;\r
+                                                                       }\r
+                                                                       file.addLine(21, P, c, w);\r
+                                                               }\r
+                                                               break;\r
+                                                       }\r
+                                                       break;\r
+\r
+                                                               case 1:\r
+                                                               {\r
+                                                                       const mglPnt p1 = gr->GetPnt(q.n1) - p0, p2 = gr->GetPnt(q.n2) - p0;\r
+\r
+                                                                       const uint32_t n = 2;\r
+                                                                       double P[2][3];\r
+                                                                       P[0][0] = p1.x;\r
+                                                                       P[0][1] = p1.y;\r
+                                                                       P[0][2] = p1.z;\r
+                                                                       P[1][0] = p2.x;\r
+                                                                       P[1][1] = p2.y;\r
+                                                                       P[1][2] = p2.z;\r
+                                                                       const RGBAColour colour((p1.r+p2.r)/2, (p1.g+p2.g)/2, (p1.b+p2.b)/2, (p1.a+p2.a)/2);\r
+                                                                       file.addLine(n, P, colour, w);\r
+                                                               }\r
+                                                               break;\r
+\r
+                                                               case 2:\r
+                                                               {\r
+                                                                       const mglPnt p1 = gr->GetPnt(q.n1)      - p0, p2 = gr->GetPnt(q.n2) - p0, p3 = gr->GetPnt(q.n3) - p0;\r
+\r
+                                                                       prctriangle triangle;\r
+                                                                       triangle.pi[0] = group.addPoint(p1);\r
+                                                                       triangle.pi[1] = group.addPoint(p2);\r
+                                                                       triangle.pi[2] = group.addPoint(p3);\r
+                                                                       triangle.ti[0] = group.addTextureCoords(p1);\r
+                                                                       triangle.ti[1] = group.addTextureCoords(p2);\r
+                                                                       triangle.ti[2] = group.addTextureCoords(p3);\r
+                                                                       group.triangles.push_back(triangle);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 3:\r
+                                                               {\r
+                                                                       const mglPnt p1 = gr->GetPnt(q.n1) - p0;\r
+                                                                       const uint32_t pi1 = group.addPoint(p1);\r
+                                                                       const uint32_t ti1 = group.addTextureCoords(p1);\r
+\r
+                                                                       const mglPnt p2 = gr->GetPnt(q.n2) - p0;\r
+                                                                       const uint32_t pi2 = group.addPoint(p2);\r
+                                                                       const uint32_t ti2 = group.addTextureCoords(p2);\r
+\r
+                                                                       const mglPnt p3 = gr->GetPnt(q.n3) - p0;\r
+                                                                       const uint32_t pi3 = group.addPoint(p3);\r
+                                                                       const uint32_t ti3 = group.addTextureCoords(p3);\r
+\r
+                                                                       const mglPnt p4 = gr->GetPnt(q.n4) - p0;\r
+                                                                       const uint32_t pi4 = group.addPoint(p4);\r
+                                                                       const uint32_t ti4 = group.addTextureCoords(p4);\r
+\r
+                                                                       prctriangle triangle1, triangle2;\r
+                                                                       triangle1.pi[0] = pi1;\r
+                                                                       triangle1.pi[1] = pi2;\r
+                                                                       triangle1.pi[2] = pi3;\r
+                                                                       triangle1.ti[0] = ti1;\r
+                                                                       triangle1.ti[1] = ti2;\r
+                                                                       triangle1.ti[2] = ti3;\r
+                                                                       group.triangles.push_back(triangle1);\r
+                                                                       triangle2.pi[0] = pi4;\r
+                                                                       triangle2.pi[1] = pi3;\r
+                                                                       triangle2.pi[2] = pi2;\r
+                                                                       triangle2.ti[0] = ti4;\r
+                                                                       triangle2.ti[1] = ti3;\r
+                                                                       triangle2.ti[2] = ti2;\r
+                                                                       group.triangles.push_back(triangle2);\r
+                                                               }\r
+                                                               break;\r
+                                                               case 4: break;  // TODO: add glyphs export later\r
+                               }\r
+                       }\r
+               }\r
+               if (!group.triangles.empty()) {\r
+                       const uint32_t nP = group.points.size();\r
+                       double (*P)[3] = new double[nP][3];\r
+                       group.writePoints(P);\r
+                       const uint32_t nI = group.triangles.size();\r
+                       uint32_t (*PI)[3] = new uint32_t[nI][3];\r
+                       for(uint32_t i = 0; i<nI; i++)\r
+                       {\r
+                               PI[i][0] = group.triangles[i].pi[0];\r
+                               PI[i][1] = group.triangles[i].pi[1];\r
+                               PI[i][2] = group.triangles[i].pi[2];\r
+                       }\r
+                       if (!group.samecolour) {\r
+                               const uint32_t nT = group.texturecoords.size();\r
+                               double (*T)[2] = new double[nT][2];\r
+                               group.writeTextureCoords(T);\r
+                               uint32_t (*TI)[3] = new uint32_t[nI][3];\r
+                               for(uint32_t i = 0; i<nI; i++)\r
+                               {\r
+                                       TI[i][0] = group.triangles[i].ti[0];\r
+                                       TI[i][1] = group.triangles[i].ti[1];\r
+                                       TI[i][2] = group.triangles[i].ti[2];\r
+                               }\r
+                               const uint32_t tess_index = file.createTriangleMesh(nP, P, nI, PI, m1, 0, NULL, NULL, nT, T, TI, 0, NULL, NULL, 0, NULL, NULL);\r
+                               file.useMesh(tess_index, materialMathGLid);\r
+                               delete [] TI;\r
+                               delete [] T;\r
+                       } else {\r
+                               const uint32_t tess_index = file.createTriangleMesh(nP, P, nI, PI, m1, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL);\r
+\r
+                               const PRCmaterial material(\r
+                                       RGBAColour(0.1,0.1,0.1,1), // ambient\r
+                                       group.colour, // diffuse\r
+                                       RGBAColour(0.1,0.1,0.1,1), //emissive\r
+                                       RGBAColour(0.0,0.0,0.0,1), //spectral\r
+                                       group.colour.A,0.1); // alpha, shininess\r
+                               file.useMesh(tess_index, file.addMaterial(material));\r
+                       }\r
+                       delete [] PI;\r
+                       delete [] P;\r
+               }\r
+               file.endgroup();\r
+               gr->Grp[i].p.clear();   // we don't need indexes anymore\r
+       }\r
+       file.finish();\r
+\r
+       if (make_pdf) {\r
+#if MGL_HAVE_PDF\r
+               const HPDF_REAL width   = dynamic_cast<mglCanvas *>(gr)->GetWidth();\r
+               const HPDF_REAL height = dynamic_cast<mglCanvas *>(gr)->GetHeight();\r
+               const HPDF_REAL depth   = sqrt(width*height);\r
+\r
+               const HPDF_Rect rect = {0, 0, width, height};\r
+\r
+               HPDF_Doc        pdf;\r
+               HPDF_Page page;\r
+               HPDF_Annotation annot;\r
+               HPDF_U3D u3d;\r
+\r
+               HPDF_Dict view;\r
+               pdf = HPDF_New (NULL, NULL);\r
+\r
+               pdf->pdf_version = HPDF_VER_17;\r
+\r
+               page = HPDF_AddPage (pdf);\r
+\r
+               HPDF_Page_SetWidth (page, width);\r
+               HPDF_Page_SetHeight (page, height);\r
+\r
+               u3d = HPDF_LoadU3DFromFile (pdf, tname);\r
+\r
+               //      Default view\r
+               view = HPDF_Create3DView (u3d->mmgr, "DefaultView");\r
+\r
+               //      Position camera\r
+               HPDF_3DView_SetCamera (view, 0, 0, 0, 0, 0, 1, depth, 0);\r
+\r
+               //      Set ortho projection\r
+               HPDF_3DView_SetOrthogonalProjection (view, 1);\r
+\r
+               //      Background color\r
+               HPDF_3DView_SetBackgroundColor (view, 0.9, 0.9, 0.9);\r
+\r
+               //      Lighting\r
+               HPDF_3DView_SetLighting (view, "CAD");\r
+\r
+               //      Add views\r
+               HPDF_U3D_Add3DView (u3d, view);\r
+               HPDF_U3D_SetDefault3DView(u3d, "DefaultView");\r
+\r
+               //      Create annotation\r
+               annot = HPDF_Page_Create3DAnnot (page, rect, u3d );\r
+\r
+               /* save the document to a file */\r
+               const size_t len = strlen(tname);\r
+               tname[len-2]='p';       tname[len-2]='d';       tname[len-1]='f';\r
+               HPDF_SaveToFile (pdf, tname);\r
+\r
+               /* clean up */\r
+               HPDF_Free (pdf);\r
+#else\r
+               const size_t len = strlen(tname);\r
+               tname[len-2]='p';       tname[len-2]='d';       tname[len-1]='f';\r
+               tname[len+0]='.';       tname[len+1]='t';       tname[len+2]='x';       tname[len+3]='t'; tname[len+4]='\0';\r
+               FILE *fp=fopen(tname,"wt");\r
+               fputs("Can not produce PDF file, MathGL compiled without PDF output support\n", fp);\r
+               fclose(fp);\r
+#endif // MGL_HAVE_PDF\r
+       }\r
+       delete []tname;\r
+}\r
+//-----------------------------------------------------------------------------\r
+void mgl_write_prc_(uintptr_t *gr, const char *fname,const char *descr, int *make_pdf,int l,int n)\r
+{      char *s=new char[l+1];  memcpy(s,fname,l);      s[l]=0;\r
+       char *f=new char[n+1];  memcpy(f,descr,n);      f[n]=0;\r
+       mgl_write_prc(_GR_,s,f,*make_pdf);      delete []s;             delete []f;     }\r
+//-----------------------------------------------------------------------------\r
diff --git a/src/prc/PRC.h b/src/prc/PRC.h
new file mode 100644 (file)
index 0000000..9ce6ea7
--- /dev/null
@@ -0,0 +1,512 @@
+#ifndef __PRC_H
+#define __PRC_H
+
+#ifdef _MSC_VER
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
+
+//const uint32_t PRCVersion=7094;   // For Adobe Reader 8 or later
+const uint32_t PRCVersion=8137; // For Adobe Reader 9 or later
+
+// from Adobe's documentation
+
+#define PRC_TYPE_Unknown                       ( (uint32_t)-1 )
+
+#define PRC_TYPE_ROOT                          0                       // This type does not correspond to any entity
+
+#define PRC_TYPE_ROOT_PRCBase                  ( PRC_TYPE_ROOT + 1 )   // Abstract root type for any PRC entity. 
+#define PRC_TYPE_ROOT_PRCBaseWithGraphics      ( PRC_TYPE_ROOT + 2 )   // Abstract root type for any PRC entity which can bear graphics. 
+
+#define PRC_TYPE_CRV                           ( PRC_TYPE_ROOT + 10 )  // Types for PRC geometrical curves
+#define PRC_TYPE_SURF                          ( PRC_TYPE_ROOT + 75 )  // Types for PRC geometrical surfaces
+#define PRC_TYPE_TOPO                          ( PRC_TYPE_ROOT + 140 ) // Types for PRC topology
+#define PRC_TYPE_TESS                          ( PRC_TYPE_ROOT + 170 ) // Types for PRC tessellation
+#define PRC_TYPE_MISC                          ( PRC_TYPE_ROOT + 200 ) // Types for PRC global data
+#define PRC_TYPE_RI                            ( PRC_TYPE_ROOT + 230 ) // Types for PRC representation items
+#define PRC_TYPE_ASM                           ( PRC_TYPE_ROOT + 300 ) // Types for PRC assembly
+#define PRC_TYPE_MKP                           ( PRC_TYPE_ROOT + 500 ) // Types for PRC markup
+#define PRC_TYPE_GRAPH                         ( PRC_TYPE_ROOT + 700 ) // Types for PRC graphics
+#define PRC_TYPE_MATH                          ( PRC_TYPE_ROOT + 900 ) // Types for PRC mathematical operators
+
+#define PRC_TYPE_CRV_Base                      ( PRC_TYPE_CRV + 1 )    // Abstract type for all geometric curves. 
+#define PRC_TYPE_CRV_Blend02Boundary           ( PRC_TYPE_CRV + 2 )    // Boundary Curve. 
+#define PRC_TYPE_CRV_NURBS                     ( PRC_TYPE_CRV + 3 )    // Non Uniform BSpline curve. 
+#define PRC_TYPE_CRV_Circle                    ( PRC_TYPE_CRV + 4 )    // Circle. 
+#define PRC_TYPE_CRV_Composite                 ( PRC_TYPE_CRV + 5 )    // Array of oriented curves. 
+#define PRC_TYPE_CRV_OnSurf                    ( PRC_TYPE_CRV + 6 )    // Curve defined by a UV curve on a surface. 
+#define PRC_TYPE_CRV_Ellipse                   ( PRC_TYPE_CRV + 7 )    // Ellipse. 
+#define PRC_TYPE_CRV_Equation                  ( PRC_TYPE_CRV + 8 )    // curve described by specific law elements 
+#define PRC_TYPE_CRV_Helix                     ( PRC_TYPE_CRV + 9 )    // Helix curve. 
+#define PRC_TYPE_CRV_Hyperbola                 ( PRC_TYPE_CRV + 10 )   // Hyperbola. 
+#define PRC_TYPE_CRV_Intersection              ( PRC_TYPE_CRV + 11 )   // Intersection between 2 surfaces. 
+#define PRC_TYPE_CRV_Line                      ( PRC_TYPE_CRV + 12 )   // Line. 
+#define PRC_TYPE_CRV_Offset                    ( PRC_TYPE_CRV + 13 )   // Offset curve. 
+#define PRC_TYPE_CRV_Parabola                  ( PRC_TYPE_CRV + 14 )   // Parabola. 
+#define PRC_TYPE_CRV_PolyLine                  ( PRC_TYPE_CRV + 15 )   // Polyedric curve. 
+#define PRC_TYPE_CRV_Transform                 ( PRC_TYPE_CRV + 16 )   // Transformed curve. 
+
+#define PRC_TYPE_SURF_Base                     ( PRC_TYPE_SURF + 1 )   // Abstract type for all geometric surfaces. 
+#define PRC_TYPE_SURF_Blend01                  ( PRC_TYPE_SURF + 2 )   // Blend surface. 
+#define PRC_TYPE_SURF_Blend02                  ( PRC_TYPE_SURF + 3 )   // Blend Surface. 
+#define PRC_TYPE_SURF_Blend03                  ( PRC_TYPE_SURF + 4 )   // Blend Surface. 
+#define PRC_TYPE_SURF_NURBS                    ( PRC_TYPE_SURF + 5 )   // Non Uniform BSpline surface. 
+#define PRC_TYPE_SURF_Cone                     ( PRC_TYPE_SURF + 6 )   // Cone. 
+#define PRC_TYPE_SURF_Cylinder                 ( PRC_TYPE_SURF + 7 )   // Cylinder. 
+#define PRC_TYPE_SURF_Cylindrical              ( PRC_TYPE_SURF + 8 )   // Surface who is defined in cylindrical space. 
+#define PRC_TYPE_SURF_Offset                   ( PRC_TYPE_SURF + 9 )   // Offset surface. 
+#define PRC_TYPE_SURF_Pipe                     ( PRC_TYPE_SURF + 10 )  // Pipe. 
+#define PRC_TYPE_SURF_Plane                    ( PRC_TYPE_SURF + 11 )  // Plane. 
+#define PRC_TYPE_SURF_Ruled                    ( PRC_TYPE_SURF + 12 )  // Ruled surface. 
+#define PRC_TYPE_SURF_Sphere                   ( PRC_TYPE_SURF + 13 )  // Sphere. 
+#define PRC_TYPE_SURF_Revolution               ( PRC_TYPE_SURF + 14 )  // Surface of revolution. 
+#define PRC_TYPE_SURF_Extrusion                        ( PRC_TYPE_SURF + 15 )  // Surface of extrusion. 
+#define PRC_TYPE_SURF_FromCurves               ( PRC_TYPE_SURF + 16 )  // Surface from two curves. 
+#define PRC_TYPE_SURF_Torus                    ( PRC_TYPE_SURF + 17 )  // Torus. 
+#define PRC_TYPE_SURF_Transform                        ( PRC_TYPE_SURF + 18 )  // Transformed surface. 
+#define PRC_TYPE_SURF_Blend04                  ( PRC_TYPE_SURF + 19 )  // defined for future use. 
+
+#define PRC_TYPE_TOPO_Context                  ( PRC_TYPE_TOPO + 1 )   // Self-containing set of topological entities. 
+#define PRC_TYPE_TOPO_Item                     ( PRC_TYPE_TOPO + 2 )   // Abstract root type for any topological entity (body or single item).
+#define PRC_TYPE_TOPO_MultipleVertex           ( PRC_TYPE_TOPO + 3 )   // Vertex whose position is the average of all edges' extremity positions to whom it belongs.
+#define PRC_TYPE_TOPO_UniqueVertex             ( PRC_TYPE_TOPO + 4 )   // Vertex with one set of coordinates (absolute position).
+#define PRC_TYPE_TOPO_WireEdge                 ( PRC_TYPE_TOPO + 5 )   // Edge belonging to a wire body / single wire body.
+#define PRC_TYPE_TOPO_Edge                     ( PRC_TYPE_TOPO + 6 )   // Edge belonging to a brep data.
+#define PRC_TYPE_TOPO_CoEdge                   ( PRC_TYPE_TOPO + 7 )   // Usage of an edge in a loop.
+#define PRC_TYPE_TOPO_Loop                     ( PRC_TYPE_TOPO + 8 )   // Array of co edges which delimits a face.
+#define PRC_TYPE_TOPO_Face                     ( PRC_TYPE_TOPO + 9 )   // Topological face delimiting a shell.
+#define PRC_TYPE_TOPO_Shell                    ( PRC_TYPE_TOPO + 10 )  // Topological shell (open or closed).
+#define PRC_TYPE_TOPO_Connex                   ( PRC_TYPE_TOPO + 11 )  // Topological region delimited by one or several shells. 
+#define PRC_TYPE_TOPO_Body                     ( PRC_TYPE_TOPO + 12 )  // Abstract root type for any topological body.
+#define PRC_TYPE_TOPO_SingleWireBody           ( PRC_TYPE_TOPO + 13 )  // Single wire body.
+#define PRC_TYPE_TOPO_BrepData                 ( PRC_TYPE_TOPO + 14 )  // Main entry to solid and surface topology (regular form).
+#define PRC_TYPE_TOPO_SingleWireBodyCompress   ( PRC_TYPE_TOPO + 15 )  // Single wire body. (ultra compressed form).
+#define PRC_TYPE_TOPO_BrepDataCompress         ( PRC_TYPE_TOPO + 16 )  // Main entry to solid and surface topology (ultra compressed form).
+#define PRC_TYPE_TOPO_WireBody                 ( PRC_TYPE_TOPO + 17 )  // This type is the main entry to wire topology. 
+
+#define PRC_TYPE_TESS_Base                     ( PRC_TYPE_TESS + 1 )   // Abstract root type for any tessellated entity. 
+#define PRC_TYPE_TESS_3D                       ( PRC_TYPE_TESS + 2 )   // Tessellated faceted data; regular form. 
+#define PRC_TYPE_TESS_3D_Compressed            ( PRC_TYPE_TESS + 3 )   // Tessellated faceted data; highly compressed form. 
+#define PRC_TYPE_TESS_Face                     ( PRC_TYPE_TESS + 4 )   // Tessellated face. 
+#define PRC_TYPE_TESS_3D_Wire                  ( PRC_TYPE_TESS + 5 )   // Tessellated wireframe. 
+#define PRC_TYPE_TESS_Markup                   ( PRC_TYPE_TESS + 6 )   // Tessellated markup. 
+
+#define PRC_TYPE_MISC_Attribute                        ( PRC_TYPE_MISC + 1 )   // Entity attribute. 
+#define PRC_TYPE_MISC_CartesianTransformation  ( PRC_TYPE_MISC + 2 )   // Cartesian transformation. 
+#define PRC_TYPE_MISC_EntityReference          ( PRC_TYPE_MISC + 3 )   // Entity reference. 
+#define PRC_TYPE_MISC_MarkupLinkedItem         ( PRC_TYPE_MISC + 4 )   // Link between a markup and an entity. 
+#define PRC_TYPE_MISC_ReferenceOnPRCBase       ( PRC_TYPE_MISC + 5 )   // Reference pointing on a regular entity (not topological). 
+#define PRC_TYPE_MISC_ReferenceOnTopology      ( PRC_TYPE_MISC + 6 )   // Reference pointing on a topological entity. 
+#define PRC_TYPE_MISC_GeneralTransformation    ( PRC_TYPE_MISC + 7 )   // General transformation.
+
+#define PRC_TYPE_RI_RepresentationItem         ( PRC_TYPE_RI + 1 )     // Basic abstract type for representation items. 
+#define PRC_TYPE_RI_BrepModel                  ( PRC_TYPE_RI + 2 )     // Basic type for surfaces and solids. 
+#define PRC_TYPE_RI_Curve                      ( PRC_TYPE_RI + 3 )     // Basic type for curves. 
+#define PRC_TYPE_RI_Direction                  ( PRC_TYPE_RI + 4 )     // Optional point + vector. 
+#define PRC_TYPE_RI_Plane                      ( PRC_TYPE_RI + 5 )     // Construction plane, as opposed to planar surface. 
+#define PRC_TYPE_RI_PointSet                   ( PRC_TYPE_RI + 6 )     // Set of points. 
+#define PRC_TYPE_RI_PolyBrepModel              ( PRC_TYPE_RI + 7 )     // Basic type to polyhedral surfaces and solids. 
+#define PRC_TYPE_RI_PolyWire                   ( PRC_TYPE_RI + 8 )     // Polyedric wireframe entity. 
+#define PRC_TYPE_RI_Set                                ( PRC_TYPE_RI + 9 )     // Logical grouping of arbitrary number of representation items. 
+#define PRC_TYPE_RI_CoordinateSystem           ( PRC_TYPE_RI + 10 )    // Coordinate system. 
+
+#define PRC_TYPE_ASM_ModelFile                 ( PRC_TYPE_ASM + 1 )    // Basic entry type for PRC. 
+#define PRC_TYPE_ASM_FileStructure             ( PRC_TYPE_ASM + 2 )    // Basic structure for PRC files. 
+#define PRC_TYPE_ASM_FileStructureGlobals      ( PRC_TYPE_ASM + 3 )    // Basic structure for PRC files : globals. 
+#define PRC_TYPE_ASM_FileStructureTree         ( PRC_TYPE_ASM + 4 )    // Basic structure for PRC files : tree. 
+#define PRC_TYPE_ASM_FileStructureTessellation ( PRC_TYPE_ASM + 5 )    // Basic structure for PRC files : tessellation. 
+#define PRC_TYPE_ASM_FileStructureGeometry     ( PRC_TYPE_ASM + 6 )    // Basic structure for PRC files : geometry. 
+#define PRC_TYPE_ASM_FileStructureExtraGeometry        ( PRC_TYPE_ASM + 7 )    // Basic structure for PRC files : extra geometry data.
+#define PRC_TYPE_ASM_ProductOccurence          ( PRC_TYPE_ASM + 10 )   // Basic contruct for assemblies. 
+#define PRC_TYPE_ASM_PartDefinition            ( PRC_TYPE_ASM + 11 )   // Basic construct for parts. 
+#define PRC_TYPE_ASM_Filter                    ( PRC_TYPE_ASM + 20 )
+
+#define PRC_TYPE_MKP_View                      ( PRC_TYPE_MKP + 1 )    // Grouping of markup by views. 
+#define PRC_TYPE_MKP_Markup                    ( PRC_TYPE_MKP + 2 )    // Basic type for simple markups. 
+#define PRC_TYPE_MKP_Leader                    ( PRC_TYPE_MKP + 3 )    // basic type for markup leader 
+#define PRC_TYPE_MKP_AnnotationItem            ( PRC_TYPE_MKP + 4 )    // Usage of a markup.
+#define PRC_TYPE_MKP_AnnotationSet             ( PRC_TYPE_MKP + 5 )    // Group of annotations.
+#define PRC_TYPE_MKP_AnnotationReference       ( PRC_TYPE_MKP + 6 )    // Logical grouping of annotations for reference.
+
+#define PRC_TYPE_GRAPH_Style                   ( PRC_TYPE_GRAPH + 1 )  // Display style. 
+#define PRC_TYPE_GRAPH_Material                        ( PRC_TYPE_GRAPH + 2 )  // Display material properties. 
+#define PRC_TYPE_GRAPH_Picture                 ( PRC_TYPE_GRAPH + 3 )  // Picture. 
+#define PRC_TYPE_GRAPH_TextureApplication      ( PRC_TYPE_GRAPH + 11 ) // Texture application. 
+#define PRC_TYPE_GRAPH_TextureDefinition       ( PRC_TYPE_GRAPH + 12 ) // Texture definition. 
+#define PRC_TYPE_GRAPH_TextureTransformation   ( PRC_TYPE_GRAPH + 13 ) // Texture transformation. 
+#define PRC_TYPE_GRAPH_LinePattern             ( PRC_TYPE_GRAPH + 21 ) // One dimensional display style. 
+#define PRC_TYPE_GRAPH_FillPattern             ( PRC_TYPE_GRAPH + 22 ) // Abstract class for two-dimensional display style. 
+#define PRC_TYPE_GRAPH_DottingPattern          ( PRC_TYPE_GRAPH + 23 ) // Two-dimensional filling with dots. 
+#define PRC_TYPE_GRAPH_HatchingPattern         ( PRC_TYPE_GRAPH + 24 ) // Two-dimensional filling with hatches. 
+#define PRC_TYPE_GRAPH_SolidPattern            ( PRC_TYPE_GRAPH + 25 ) // Two-dimensional filling with particular style (color, material, texture). 
+#define PRC_TYPE_GRAPH_VPicturePattern         ( PRC_TYPE_GRAPH + 26 ) // Two-dimensional filling with vectorised picture. 
+#define PRC_TYPE_GRAPH_AmbientLight            ( PRC_TYPE_GRAPH + 31 ) // Scene ambient illumination. 
+#define PRC_TYPE_GRAPH_PointLight              ( PRC_TYPE_GRAPH + 32 ) // Scene point illumination. 
+#define PRC_TYPE_GRAPH_DirectionalLight                ( PRC_TYPE_GRAPH + 33 ) // Scene directional illumination. 
+#define PRC_TYPE_GRAPH_SpotLight               ( PRC_TYPE_GRAPH + 34 ) // Scene spot illumination. 
+#define PRC_TYPE_GRAPH_SceneDisplayParameters  ( PRC_TYPE_GRAPH + 41 ) // Parameters for scene visualisation. 
+#define PRC_TYPE_GRAPH_Camera                  ( PRC_TYPE_GRAPH + 42 ) // 
+
+#define PRC_TYPE_MATH_FCT_1D                   ( PRC_TYPE_MATH + 1 )   // Basic type for one degree equation object. 
+#define PRC_TYPE_MATH_FCT_1D_Polynom           ( PRC_TYPE_MATH_FCT_1D + 1 )    // Polynomial equation. 
+#define PRC_TYPE_MATH_FCT_1D_Trigonometric     ( PRC_TYPE_MATH_FCT_1D + 2 )    // Cosinus based equation. 
+#define PRC_TYPE_MATH_FCT_1D_Fraction          ( PRC_TYPE_MATH_FCT_1D + 3 )    // Fraction between 2 one degree equation object. 
+#define PRC_TYPE_MATH_FCT_1D_ArctanCos         ( PRC_TYPE_MATH_FCT_1D + 4 )    // Specific equation. 
+#define PRC_TYPE_MATH_FCT_1D_Combination       ( PRC_TYPE_MATH_FCT_1D + 5 )    // Combination of one degree equation object. 
+#define PRC_TYPE_MATH_FCT_3D                   ( PRC_TYPE_MATH + 10 )  // Basic type for 3rd degree equation object. 
+#define PRC_TYPE_MATH_FCT_3D_Linear            ( PRC_TYPE_MATH_FCT_3D + 1 )    // Linear transformation ( with a matrix ). 
+#define PRC_TYPE_MATH_FCT_3D_NonLinear         ( PRC_TYPE_MATH_FCT_3D + 2 )    // Specific transformation. 
+
+#define PRC_PRODUCT_FLAG_DEFAULT        0x0001
+#define PRC_PRODUCT_FLAG_INTERNAL       0x0002
+#define PRC_PRODUCT_FLAG_CONTAINER      0x0004
+#define PRC_PRODUCT_FLAG_CONFIG         0x0008
+#define PRC_PRODUCT_FLAG_VIEW           0x0010
+
+#define PRC_TRANSFORMATION_Identity     0x00
+#define PRC_TRANSFORMATION_Translate    0x01
+#define PRC_TRANSFORMATION_Rotate       0x02
+#define PRC_TRANSFORMATION_Mirror       0x04
+#define PRC_TRANSFORMATION_Scale        0x08
+#define PRC_TRANSFORMATION_NonUniformScale 0x10
+#define PRC_TRANSFORMATION_NonOrtho     0x20
+#define PRC_TRANSFORMATION_Homogeneous  0x40
+
+#define PRC_FACETESSDATA_Polyface                          0x0001
+#define PRC_FACETESSDATA_Triangle                          0x0002
+#define PRC_FACETESSDATA_TriangleFan                       0x0004
+#define PRC_FACETESSDATA_TriangleStripe                    0x0008
+#define PRC_FACETESSDATA_PolyfaceOneNormal                 0x0010
+#define PRC_FACETESSDATA_TriangleOneNormal                 0x0020
+#define PRC_FACETESSDATA_TriangleFanOneNormal              0x0040
+#define PRC_FACETESSDATA_TriangleStripeOneNormal           0x0080
+#define PRC_FACETESSDATA_PolyfaceTextured                  0x0100
+#define PRC_FACETESSDATA_TriangleTextured                  0x0200
+#define PRC_FACETESSDATA_TriangleFanTextured               0x0400
+#define PRC_FACETESSDATA_TriangleStripeTextured            0x0800
+#define PRC_FACETESSDATA_PolyfaceOneNormalTextured         0x1000
+#define PRC_FACETESSDATA_TriangleOneNormalTextured         0x2000
+#define PRC_FACETESSDATA_TriangleFanOneNormalTextured      0x4000
+#define PRC_FACETESSDATA_TriangleStripeOneNormalTextured   0x8000
+#define PRC_FACETESSDATA_NORMAL_Single                 0x40000000
+#define PRC_FACETESSDATA_NORMAL_Mask                   0x3FFFFFFF
+#define PRC_FACETESSDATA_WIRE_IsNotDrawn               0x4000          // Indicates that the edge should not be drawn (its neighbor will be drawn).
+#define PRC_FACETESSDATA_WIRE_IsClosing                        0x8000          // Indicates that this is the last edge of a loop.
+
+#define PRC_3DWIRETESSDATA_IsClosing                   0x10000000 // Indicates that the first point is implicitely repeated after the last one to close the wire edge.
+#define PRC_3DWIRETESSDATA_IsContinuous                        0x20000000 // Indicates that the last point of the preceding wire should be linked with the first point of the current one.
+
+#define PRC_TEXTURE_MAPPING_DIFFUSE                    0x0001 // Diffuse texture mapping attribute. Default value.
+#define PRC_TEXTURE_MAPPING_BUMP                       0x0002 // Bump texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_OPACITY                    0x0004 // Opacity texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_SPHERICAL_REFLECTION       0x0008 // Spherical reflection texture mapping attribute (used for environment mapping).
+#define PRC_TEXTURE_MAPPING_CUBICAL_REFLECTION         0x0010 // Cubical reflection texture mapping attribute (used for environment mapping).
+#define PRC_TEXTURE_MAPPING_REFRACTION                 0x0020 // Refraction texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_SPECULAR                   0x0040 // Specular texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_AMBIENT                    0x0080 // Ambient texture mapping attribute.
+#define PRC_TEXTURE_MAPPING_EMISSION                   0x0100 // Emission texture mapping attribute.
+
+#define PRC_TEXTURE_APPLYING_MODE_NONE         0x00 // let the application choose
+#define PRC_TEXTURE_APPLYING_MODE_LIGHTING     0x01 // use lighting mode
+#define PRC_TEXTURE_APPLYING_MODE_ALPHATEST    0x02 // use alpha test
+#define PRC_TEXTURE_APPLYING_MODE_VERTEXCOLOR  0x04 // combine a texture with one-color-per-vertex mode
+
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RED     0x0001 // Red texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_GREEN   0x0002 // Green texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_BLUE    0x0004 // Blue texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RGB     0x0007 // RGB texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_ALPHA   0x0008 // Alpha texture mapping component.
+#define PRC_TEXTURE_MAPPING_COMPONENTS_RGBA    0x000F // RGBA texture mapping component.
+
+enum EPRCModellerAttributeType {
+  KEPRCModellerAttributeTypeNull = 0,
+  KEPRCModellerAttributeTypeInt = 1,
+  KEPRCModellerAttributeTypeReal = 2,
+  KEPRCModellerAttributeTypeTime = 3,
+  KEPRCModellerAttributeTypeString = 4
+};
+
+enum EPRCPictureDataFormat {
+  KEPRCPicture_PNG,
+  KEPRCPicture_JPG,
+  KEPRCPicture_BITMAP_RGB_BYTE,
+  KEPRCPicture_BITMAP_RGBA_BYTE,
+  KEPRCPicture_BITMAP_GREY_BYTE,
+  KEPRCPicture_BITMAP_GREYA_BYTE
+};
+
+enum EPRCProductLoadStatus {
+  KEPRCProductLoadStatus_Unknown = 0,
+  KEPRCProductLoadStatus_Error,
+  KEPRCProductLoadStatus_NotLoaded,
+  KEPRCProductLoadStatus_NotLoadable,
+  KEPRCProductLoadStatus_Loaded
+};
+
+enum EPRCExtendType { 
+  KEPRCExtendTypeNone = 0,      // Discontinuous position.
+  KEPRCExtendTypeExt1 = 2,      // Same as EPRCExtendTypeCInfinity.
+  KEPRCExtendTypeExt2 = 4,      // Same as EPRCExtendTypeG1R for surface, and EPRCExtendTypeG1 for curve.
+  KEPRCExtendTypeG1 = 6,        // Continuous in direction but not magnitude of first derivative.
+  KEPRCExtendTypeG1R = 8,       // Surface extended with a ruled surface that connects with G1-continuity.
+  KEPRCExtendTypeG1_G2 = 10,    // Extended by reflection, yielding a G2 continuous extension.
+  KEPRCExtendTypeCInfinity = 12 // Unlimited continuity.
+};
+
+enum EPRCKnotType {                    // Knot vector type
+  KEPRCKnotTypeUniformKnots,           // Uniform knot vector.
+  KEPRCKnotTypeUnspecified,            // Unspecified knot type.
+  KEPRCKnotTypeQuasiUniformKnots,      // Quasi-uniform knot vector.
+  KEPRCKnotTypePiecewiseBezierKnots    // Extrema with multiplicities of degree +1.
+};                                     // Note : this value is currently unused and should be set to KEPRCKnotTypeUnspecified.
+
+
+enum EPRCBSplineSurfaceForm {
+  KEPRCBSplineSurfaceFormPlane,                        // Planar surface.
+  KEPRCBSplineSurfaceFormCylindrical,          // Cylindrical surface.
+  KEPRCBSplineSurfaceFormConical,              // Conical surface.
+  KEPRCBSplineSurfaceFormSpherical,            // Spherical surface.
+  KEPRCBSplineSurfaceFormRevolution,           // Surface of revolution.
+  KEPRCBSplineSurfaceFormRuled,                        // Ruled surface.
+  KEPRCBSplineSurfaceFormGeneralizedCone,      // Cone.
+  KEPRCBSplineSurfaceFormQuadric,              // Quadric surface.
+  KEPRCBSplineSurfaceFormLinearExtrusion,      // Surface of extrusion.
+  KEPRCBSplineSurfaceFormUnspecified,          // Unspecified surface.
+  KEPRCBSplineSurfaceFormPolynomial            // Polynomial surface.
+};
+
+enum EPRCBSplineCurveForm {            // NURBS curve form
+  KEPRCBSplineCurveFormUnspecified,    // Unspecified curve form.
+  KEPRCBSplineCurveFormPolyline,       // Polygon.
+  KEPRCBSplineCurveFormCircularArc,    // Circle arc.
+  KEPRCBSplineCurveFormEllipticArc,    // Elliptical arc.
+  KEPRCBSplineCurveFormParabolicArc,   // Parabolic arc.
+  KEPRCBSplineCurveFormHyperbolicArc   // Hyperbolic arc.
+};                                     // Note : this value is currently unused and should be set to KEPRCBSplineCurveFormUnspecified.
+
+enum EPRCTextureMappingType {                  // Defines how to retrieve mapping coordinates.
+  KEPRCTextureMappingType_Unknown,             // Let the application choose.
+  KEPRCTextureMappingType_Stored,              // Use the mapping coordinates that are stored on a 3D tessellation object
+  KEPRCTextureMappingType_Parametric,          // Retrieve the UV coordinates on the surface as mapping coordinates
+  KEPRCTextureMappingType_Operator             // Use the defined Texture mapping operator to calculate mapping coordinates
+};
+
+enum EPRCTextureFunction {                     // Defines how to paint a texture on the surface being rendered.
+  KEPRCTextureFunction_Unknown,                        // Let the application choose.
+  KEPRCTextureFunction_Modulate,               // Combine lighting with texturing. This is the default value.
+  KEPRCTextureFunction_Replace,                        // Replace the object color with texture color data.
+  KEPRCTextureFunction_Blend,                  // Reserved for future use.
+  KEPRCTextureFunction_Decal                   // Reserved for future use.
+};
+
+enum EPRCTextureMappingOperator {              // The operator to use when computing mapping coordinates.
+  KEPRCTextureMappingOperator_Unknown,         // Default value
+  KEPRCTextureMappingOperator_Planar,          // Reserved for future use
+  KEPRCTextureMappingOperator_Cylindrical,     // Reserved for future use
+  KEPRCTextureMappingOperator_Spherical,       // Reserved for future use
+  KEPRCTextureMappingOperator_Cubical          // Reserved for future use
+};
+
+enum EPRCTextureBlendParameter {               // Reserved for future use. Defines how to apply blending.
+  KEPRCTextureBlendParameter_Unknown,          // Default value.
+  KEPRCTextureBlendParameter_Zero,             // Reserved for future use.
+  KEPRCTextureBlendParameter_One,              // Reserved for future use.
+  KEPRCTextureBlendParameter_SrcColor,         // Reserved for future use.
+  KEPRCTextureBlendParameter_OneMinusSrcColor, // Reserved for future use.
+  KEPRCTextureBlendParameter_DstColor,         // Reserved for future use.
+  KEPRCTextureBlendParameter_OneMinusDstColor, // Reserved for future use.
+  KEPRCTextureBlendParameter_SrcAlpha,         // Reserved for future use.
+  KEPRCTextureBlendParameter_OneMinusSrcAlpha, // Reserved for future use.
+  KEPRCTextureBlendParameter_DstAlpha,         // Reserved for future use.
+  KEPRCTextureBlendParameter_OneMinusDstAlpha, // Reserved for future use.
+  KEPRCTextureBlendParameter_SrcAlphaSaturate  // Reserved for future use.
+};
+
+enum EPRCTextureWrappingMode {                 // Defines repeating and clamping texture modes.
+  KEPRCTextureWrappingMode_Unknown,            // Let the application choose.
+  KEPRCTextureWrappingMode_Repeat,             // Display the repeated texture on the surface.
+  KEPRCTextureWrappingMode_ClampToBorder,      // Clamp the texture to the border. Display the surface color along the texture limits.
+  KEPRCTextureWrappingMode_Clamp,              // Reserved for future use.
+  KEPRCTextureWrappingMode_ClampToEdge,                // Reserved for future use.
+  KEPRCTextureWrappingMode_MirroredRepeat      // Reserved for future use.
+};
+
+enum EPRCTextureAlphaTest {                    // Reserved for future use. Defines how to use a texture alpha test.
+  KEPRCTextureAlphaTest_Unknown,               // Default value.
+  KEPRCTextureAlphaTest_Never,                 // Reserved for future use.
+  KEPRCTextureAlphaTest_Less,                  // Reserved for future use.
+  KEPRCTextureAlphaTest_Equal,                 // Reserved for future use.
+  KEPRCTextureAlphaTest_Lequal,                        // Reserved for future use.
+  KEPRCTextureAlphaTest_Greater,               // Reserved for future use.
+  KEPRCTextureAlphaTest_Notequal,              // Reserved for future use.
+  KEPRCTextureAlphaTest_Gequal,                        // Reserved for future use.
+  KEPRCTextureAlphaTest_Always                 // Reserved for future use.
+};
+
+
+// Bit field for graphics behavior
+#define PRC_GRAPHICS_Show                      0x0001 // The entity is shown.
+#define PRC_GRAPHICS_SonHeritShow              0x0002 // Shown entity son inheritance.
+#define PRC_GRAPHICS_FatherHeritShow           0x0004 // Shown entity father inheritance.
+#define PRC_GRAPHICS_SonHeritColor             0x0008 // Color/material son inheritance.
+#define PRC_GRAPHICS_FatherHeritColor          0x0010 // Color/material father inheritance.
+#define PRC_GRAPHICS_SonHeritLayer             0x0020 // Layer son inheritance.
+#define PRC_GRAPHICS_FatherHeritLayer          0x0040 // Layer father inheritance.
+#define PRC_GRAPHICS_SonHeritTransparency      0x0080 // Transparency son inheritance.
+#define PRC_GRAPHICS_FatherHeritTransparency   0x0100 // Transparency father inheritance.
+#define PRC_GRAPHICS_SonHeritLinePattern       0x0200 // Line pattern son inheritance.
+#define PRC_GRAPHICS_FatherHeritLinePattern    0x0400 // Line pattern father inheritance.
+#define PRC_GRAPHICS_SonHeritLineWidth         0x0800 // Line width son inheritance.
+#define PRC_GRAPHICS_FatherHeritLineWidth      0x1000 // Line width father inheritance.
+#define PRC_GRAPHICS_Removed                   0x2000 // The entity has been removed and no longer appears in the tree.
+
+enum EPRCMarkupType {
+  KEPRCMarkupType_Unknown = 0,
+  KEPRCMarkupType_Text,
+  KEPRCMarkupType_Dimension,
+  KEPRCMarkupType_Arrow,
+  KEPRCMarkupType_Balloon,
+  KEPRCMarkupType_CircleCenter,
+  KEPRCMarkupType_Coordinate,
+  KEPRCMarkupType_Datum,
+  KEPRCMarkupType_Fastener,
+  KEPRCMarkupType_Gdt,
+  KEPRCMarkupType_Locator,
+  KEPRCMarkupType_MeasurementPoint,
+  KEPRCMarkupType_Roughness,
+  KEPRCMarkupType_Welding,
+  KEPRCMarkupType_Table,
+  KEPRCMarkupType_Other 
+};
+
+enum EPRCMarkupSubType {
+  KEPRCMarkupSubType_Unknown = 0,
+  KEPRCMarkupSubType_EnumMax,
+
+  KEPRCMarkupSubType_Datum_Ident = 1 ,
+  KEPRCMarkupSubType_Datum_EnumMax, 
+
+  KEPRCMarkupSubType_Dimension_Distance = 1,
+  KEPRCMarkupSubType_Dimension_Radius_Tangent,
+  KEPRCMarkupSubType_Dimension_Radius_Cylinder,
+  KEPRCMarkupSubType_Dimension_Radius_Edge,
+  KEPRCMarkupSubType_Dimension_Diameter,
+  KEPRCMarkupSubType_Dimension_Diameter_Tangent,
+  KEPRCMarkupSubType_Dimension_Diameter_Cylinder,
+  KEPRCMarkupSubType_Dimension_Diameter_Edge, 
+  KEPRCMarkupSubType_Dimension_Diameter_Cone,
+  KEPRCMarkupSubType_Dimension_Length,
+  KEPRCMarkupSubType_Dimension_Length_Curvilinear,
+  KEPRCMarkupSubType_Dimension_Length_Circular,
+  KEPRCMarkupSubType_Dimension_Angle,
+  KEPRCMarkupSubType_Dimension_EnumMax,
+
+  KEPRCMarkupSubType_Gdt_Fcf = 1,
+  KEPRCMarkupSubType_Gdt_EnumMax,
+
+  KEPRCMarkupSubType_Welding_Line = 1,
+  KEPRCMarkupSubType_Welding_EnumMax,
+
+  KEPRCMarkupSubType_Other_Symbol_User = 1,
+  KEPRCMarkupSubType_Other_EnumMax 
+};
+
+#define PRC_MARKUP_IsHidden            0x01    // The tessellation is hidden.
+#define PRC_MARKUP_HasFrame            0x02    // The tessellation has a frame.
+#define PRC_MARKUP_IsNotModifiable     0x04    // The tessellation is given and should not be modified.
+#define PRC_MARKUP_IsZoomable          0x08    // The tessellation has zoom capability.
+#define PRC_MARKUP_IsOnTop             0x10    // The tessellation is on top of the geometry.
+#define PRC_MARKUP_IsFlipable          0x20    // The text tessellation can be flipped to always be readable on screen. This value is currently unused.
+
+#define PRC_RENDERING_PARAMETER_SPECIAL_CULLING        0x0001 // special culling strategy to apply
+#define PRC_RENDERING_PARAMETER_FRONT_CULLING  0x0002 // apply front culling (ignored if no special culling strategy)
+#define PRC_RENDERING_PARAMETER_BACK_CULLING   0x0004 // apply back culling (ignored if no special culling strategy)
+#define PRC_RENDERING_PARAMETER_NO_LIGHT       0x0008 // if set, no light will apply on corresponding object
+
+#define PRC_MARKUP_IsMatrix            0x08000000 // Bit to denote that the current entity is a matrix.
+#define PRC_MARKUP_IsExtraData         0x04000000 // Bit to denote that the current entity is extra data (it is neither a matrix nor a polyline).
+#define PRC_MARKUP_IntegerMask         0xFFFFF    // Integer mask to retrieve sizes.
+#define PRC_MARKUP_ExtraDataType       0x3E00000  // Mask to retrieve the integer type of the entity.
+
+#define PRC_MARKUP_ExtraDataType_Pattern       (( 0<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Picture       (( 1<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Triangles     (( 2<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Quads         (( 3<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FaceViewMode  (( 6<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FrameDrawMode (( 7<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_FixedSizeMode (( 8<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Symbol                (( 9<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Cylinder      ((10<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Color         ((11<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_LineStipple   ((12<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Font          ((13<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Text          ((14<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Points                ((15<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_Polygon       ((16<<21)|PRC_MARKUP_IsExtraData)
+#define PRC_MARKUP_ExtraDataType_LineWidth     ((17<<21)|PRC_MARKUP_IsExtraData)
+
+enum EPRCCharSet
+{
+  KEPRCCharsetUnknown = -1,
+  KEPRCCharsetRoman = 0,
+  KEPRCCharsetJapanese,
+  KEPRCCharsetTraditionalChinese,
+  KEPRCCharsetKorean,
+  KEPRCCharsetArabic,
+  KEPRCCharsetHebrew,
+  KEPRCCharsetGreek,
+  KEPRCCharsetCyrillic,
+  KEPRCCharsetRightLeft,
+  KEPRCCharsetDevanagari,
+  KEPRCCharsetGurmukhi,
+  KEPRCCharsetGujarati,
+  KEPRCCharsetOriya,
+  KEPRCCharsetBengali,
+  KEPRCCharsetTamil,
+  KEPRCCharsetTelugu,
+  KEPRCCharsetKannada,
+  KEPRCCharsetMalayalam,
+  KEPRCCharsetSinhalese,
+  KEPRCCharsetBurmese,
+  KEPRCCharsetKhmer,
+  KEPRCCharsetThai,
+  KEPRCCharsetLaotian,
+  KEPRCCharsetGeorgian,
+  KEPRCCharsetArmenian,
+  KEPRCCharsetSimplifiedChinese,
+  KEPRCCharsetTibetan,
+  KEPRCCharsetMongolian,
+  KEPRCCharsetGeez,
+  KEPRCCharsetEastEuropeanRoman,
+  KEPRCCharsetVietnamese,
+  KEPRCCharsetExtendedArabic
+};
+
+#define PRC_Font_Bold         0x02    /*!< Bold. */
+#define PRC_Font_Italic       0x04    /*!< Italic. */
+#define PRC_Font_Underlined   0x08    /*!< Underlined. */
+#define PRC_Font_StrikedOut   0x10    /*!< Striked-out. */
+#define PRC_Font_Overlined    0x20    /*!< Overlined. */
+#define PRC_Font_Streched     0x40    /*!< Streched. In case the font used is not the original font, it indicates that the text needs to be stretched to fit its bounding box. */
+#define PRC_Font_Wired        0x80    /*!< Wired. Indicates that the original font is a wirefame font. */
+#define PRC_Font_FixedWidth   0x100   /*!< Fixed width. Indicates that the original font is not proportional (each glyph has the same width). */
+
+#define PRC_CONTEXT_OuterLoopFirst 0x0001 // Outer loops are always first loops (specific to PRC_TYPE_TOPO_BrepData). 
+#define PRC_CONTEXT_NoClamp        0x0002 // UV curves are clamped on the surface (specific to PRC_TYPE_TOPO_BrepData). 
+#define PRC_CONTEXT_NoSplit        0x0004 // Faces are split (specific to PRC_TYPE_TOPO_BrepData). 
+
+#define PRC_BODY_BBOX_Evaluation 0x0001 // Bounding box based on geometry. 
+#define PRC_BODY_BBOX_Precise    0x0002 // Bounding box based on tessellation. 
+#define PRC_BODY_BBOX_CADData    0x0003 // Bounding box given by a CAD data file. 
+
+#endif // __PRC_H
diff --git a/src/prc/PRCbitStream.cc b/src/prc/PRCbitStream.cc
new file mode 100644 (file)
index 0000000..bb013dc
--- /dev/null
@@ -0,0 +1,403 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <zlib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cassert>
+#include "PRCbitStream.h"
+#include "PRCdouble.h"
+
+using std::string;
+using std::cerr;
+using std::endl;
+
+void PRCbitStream::compress()
+{
+  const int CHUNK= 1024; // is this reasonable?
+  compressedDataSize = 0;
+
+  z_stream strm;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+  if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+  {
+    cerr << "Compression initialization failed" << endl;
+    return;
+  }
+  unsigned int sizeAvailable = deflateBound(&strm,getSize());
+  uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+  strm.avail_in = getSize();
+  strm.next_in = (unsigned char*)data;
+  strm.next_out = (unsigned char*)compressedData;
+  strm.avail_out = sizeAvailable;
+
+  int code;
+  unsigned int chunks = 0;
+  while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+  {
+    ++chunks;
+    // strm.avail_out should be 0 if we got Z_OK
+    compressedDataSize = sizeAvailable - strm.avail_out;
+    compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+    strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+    strm.avail_out += CHUNK;
+    sizeAvailable += CHUNK;
+  }
+  compressedDataSize = sizeAvailable-strm.avail_out;
+
+  if(code != Z_STREAM_END)
+  {
+    cerr << "Compression error" << endl;
+    deflateEnd(&strm);
+    free(compressedData);
+    return;
+  }
+
+  compressed = true;
+
+  free(data);
+  data = compressedData;
+
+  deflateEnd(&strm);
+}
+
+void PRCbitStream::write(std::ostream &out) const
+{
+  if(compressed)
+  {
+    out.write((char*)data,compressedDataSize);
+  }
+  else
+  {
+     cerr << "Attempt to write stream before compression." << endl;
+     exit(1);
+  }
+}
+
+unsigned int PRCbitStream::getSize() const
+{
+  if(compressed)
+    return compressedDataSize;
+  else
+    return byteIndex+1;
+}
+
+uint8_t* PRCbitStream::getData()
+{
+  return data;
+}
+
+PRCbitStream& PRCbitStream::operator <<(bool b)
+{
+  writeBit(b);
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint32_t u)
+{
+  while(u != 0)
+  {
+    writeBit(1);
+    writeByte(u & 0xFF);
+    u >>= 8;
+  }
+  writeBit(0);
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(uint8_t u)
+{
+  writeByte(u);
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(int32_t i)
+{
+  uint8_t lastByte = 0;
+  //while(!((current value is 0 and last byte was positive) OR (current value is -1 and last value was negative)))
+  while(!(((i == 0)&&((lastByte & 0x80)==0))||((i == -1)&&((lastByte & 0x80) != 0))))
+  {
+    writeBit(1);
+    lastByte = i & 0xFF;
+    writeByte(lastByte);
+    i >>= 8;
+  }
+  writeBit(0);
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(double value)
+{
+  // write a double
+  if(compressed)
+  {
+    cerr << "Cannot write to a stream that has been compressed." << endl;
+    return *this;
+  }
+  union ieee754_double *pid=(union ieee754_double *)&value;
+  int
+        i,
+        fSaveAtEnd;
+        PRCbyte
+        *pb,
+        *pbStart,
+        *pbStop,
+        *pbEnd,
+        *pbResult,
+        bSaveAtEnd = 0;
+  struct sCodageOfFrequentDoubleOrExponent
+        cofdoe,
+        *pcofdoe;
+
+  cofdoe.u2uod.Value=value;
+  pcofdoe = (struct sCodageOfFrequentDoubleOrExponent *)bsearch(
+                           &cofdoe,
+                           acofdoe,
+                           sizeof(acofdoe)/sizeof(pcofdoe[0]),
+                           sizeof(pcofdoe[0]),
+                           stCOFDOECompare);
+
+  while(pcofdoe>acofdoe && EXPONENT(pcofdoe->u2uod.Value)==EXPONENT((pcofdoe-1)->u2uod.Value))
+    pcofdoe--;
+
+  assert(pcofdoe);
+  while(pcofdoe->Type==VT_double)
+  {
+    if(fabs(value)==pcofdoe->u2uod.Value)
+      break;
+    pcofdoe++;
+  }
+
+  for(i=1<<(pcofdoe->NumberOfBits-1);i>=1;i>>=1)
+    writeBit((pcofdoe->Bits&i)!=0);
+
+  if
+  (
+    !memcmp(&value,stadwZero,sizeof(value))
+    ||      !memcmp(&value,stadwNegativeZero,sizeof(value))
+  )
+    return *this;
+
+  writeBit(pid->ieee.negative);
+
+  if(pcofdoe->Type==VT_double)
+    return *this;
+
+  if(pid->ieee.mantissa0==0 && pid->ieee.mantissa1==0)
+  {
+    writeBit(0);
+    return *this;
+  }
+
+  writeBit(1);
+
+#ifdef WORDS_BIGENDIAN
+  pb=((PRCbyte *)&value)+1;
+#else
+  pb=((PRCbyte *)&value)+6;
+#endif
+  //add_bits((*pb)&0x0f,4 STAT_V STAT_DOUBLE);
+  writeBits((*pb)&0x0F,4);
+
+  NEXTBYTE(pb);
+  pbStart=pb;
+#ifdef WORDS_BIGENDIAN
+  pbEnd=
+  pbStop= ((PRCbyte *)(&value+1))-1;
+#else
+  pbEnd=
+  pbStop= ((PRCbyte *)&value);
+#endif
+
+  if((fSaveAtEnd=(*pbStop!=*BEFOREBYTE(pbStop)))!=0)
+    bSaveAtEnd=*pbEnd;
+  PREVIOUSBYTE(pbStop);
+
+  while(*pbStop==*BEFOREBYTE(pbStop))
+    PREVIOUSBYTE(pbStop);
+
+  for(;MOREBYTE(pb,pbStop);NEXTBYTE(pb))
+  {
+    if(pb!=pbStart && (pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+    {
+      writeBit(0);
+      writeBits(DIFFPOINTERS(pb,pbResult),3);
+    }
+    else
+    {
+      writeBit(1);
+      writeByte(*pb);
+    }
+  }
+
+  if(!MOREBYTE(BEFOREBYTE(pbEnd),pbStop))
+  {
+    if(fSaveAtEnd)
+    {
+      writeBit(0);
+      writeBits(6,3);
+      writeByte(bSaveAtEnd);
+    }
+    else
+    {
+      writeBit(0);
+      writeBits(0,3);
+    }
+  }
+  else
+  {
+    if((pbResult=SEARCHBYTE(BEFOREBYTE(pb),*pb,DIFFPOINTERS(pb,pbStart)))!=NULL)
+    {
+      writeBit(0);
+      writeBits(DIFFPOINTERS(pb,pbResult),3);
+    }
+    else
+    {
+      writeBit(1);
+      writeByte(*pb);
+    }
+  }
+
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const char* s)
+{
+  if (s == NULL)
+  {
+    writeBit(false); // string is NULL
+    return *this;
+  }
+  string str(s);
+  *this << str;
+  return *this;
+}
+
+PRCbitStream& PRCbitStream::operator <<(const string& s)
+{
+  if(s == "")
+  {
+    writeBit(false); // string is NULL
+    return *this;
+  }
+  writeBit(true);
+  size_t l = s.length();
+  *this << static_cast<uint32_t>(l);
+  for(size_t i = 0; i < l; ++i)
+    writeByte(s[i]);
+  return *this;
+}
+
+void PRCbitStream::writeBit(bool b)
+{
+  if(compressed)
+  {
+    cerr << "Cannot write to a stream that has been compressed." << endl;
+    return;
+  }
+
+  if(b)
+  {
+    data[byteIndex] |= (0x80 >> bitIndex);
+  }
+  nextBit();
+}
+
+void PRCbitStream::writeBits(uint32_t u, uint8_t bits)
+{
+  if(bits > 32)
+    return;
+  else
+  {
+    for(uint32_t mask = (1 << (bits-1)); mask != 0; mask >>= 1)
+    {
+      writeBit((u&mask) != 0);
+    }
+  }
+}
+
+void PRCbitStream::writeByte(uint8_t u)
+{
+  if(compressed)
+  {
+    cerr << "Cannot write to a stream that has been compressed." << endl;
+    return;
+  }
+
+  if(bitIndex == 0)
+  {
+    data[byteIndex] = u;
+    nextByte();
+  }
+  else
+  {
+    data[byteIndex] |= (u >> bitIndex);
+    unsigned int obi = bitIndex;
+    nextByte();
+    data[byteIndex] |= (u << (8-obi));
+    bitIndex = obi; // bit index is not changed by writing 8 bits
+  }
+}
+
+void PRCbitStream::nextBit()
+{
+  ++bitIndex;
+  if(bitIndex == 8)
+  {
+    nextByte();
+  }
+}
+
+void PRCbitStream::nextByte()
+{
+  ++byteIndex;
+  if(byteIndex >= allocatedLength)
+    getAChunk();
+  data[byteIndex] = 0; // clear the garbage data
+  bitIndex = 0;
+}
+
+void PRCbitStream::getAChunk()
+{
+   if(allocatedLength==0)
+     data = (uint8_t*)realloc((void*)data,CHUNK_SIZE);
+   else
+     data = (uint8_t*)realloc((void*)data,2*allocatedLength);
+
+   if(data != NULL)
+   {
+     if(allocatedLength==0)
+     {
+       allocatedLength = CHUNK_SIZE;
+       *data = 0; // clear first byte
+     }
+     else
+       allocatedLength *= 2;
+   }
+   else
+   {
+     // warn about memory problem!
+     cerr << "Memory allocation error." << endl;
+     exit(1);
+   }
+}
diff --git a/src/prc/PRCbitStream.h b/src/prc/PRCbitStream.h
new file mode 100644 (file)
index 0000000..6714258
--- /dev/null
@@ -0,0 +1,86 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __PRC_BIT_STREAM_H
+#define __PRC_BIT_STREAM_H
+
+#ifdef _MSC_VER
+#include <stdio.h>
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#endif // _MSC_VER >= 1600
+#else
+#include <inttypes.h>
+#endif // _MSC_VER
+#include <string>
+#include <iostream>
+#include <stdlib.h>
+
+#define CHUNK_SIZE (1024)
+// Is this a reasonable initial size?
+
+class PRCbitStream
+{
+  public:
+    PRCbitStream(uint8_t*& buff, unsigned int l) : byteIndex(0), bitIndex(0),
+                 allocatedLength(l), data(buff), compressed(false)
+    {
+      if(data == 0)
+      {
+        getAChunk();
+      }
+    }
+
+    unsigned int getSize() const;
+    uint8_t* getData();
+
+    PRCbitStream& operator <<(const std::string&);
+    PRCbitStream& operator <<(bool);
+    PRCbitStream& operator <<(uint32_t);
+    PRCbitStream& operator <<(uint8_t);
+    PRCbitStream& operator <<(int32_t);
+    PRCbitStream& operator <<(double);
+    PRCbitStream& operator <<(const char*);
+
+    void compress();
+    void write(std::ostream &out) const;
+  private:
+    void writeBit(bool);
+    void writeBits(uint32_t,uint8_t);
+    void writeByte(uint8_t);
+    void nextByte();
+    void nextBit();
+    void getAChunk();
+    // bitIndex is "big endian", zero based, location of next bit to write
+    unsigned int byteIndex,bitIndex;
+    unsigned int allocatedLength;
+    uint8_t*& data;
+    bool compressed;
+    uint32_t compressedDataSize;
+};
+
+#endif // __PRC_BIT_STREAM_H
diff --git a/src/prc/PRCdouble.cc b/src/prc/PRCdouble.cc
new file mode 100644 (file)
index 0000000..69d4b02
--- /dev/null
@@ -0,0 +1,2121 @@
+#include "PRCdouble.h"
+
+// from Adobe's documentation
+
+PRCdword stadwZero[2]={DOUBLEWITHTWODWORD(0x00000000,0x00000000)};
+PRCdword stadwNegativeZero[2]={DOUBLEWITHTWODWORD(0x80000000,0x00000000)};
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned Bits, short NumberOfBits)
+{
+  struct sCodageOfFrequentDoubleOrExponent *pcofdoe;
+  for(pcofdoe=acofdoe; pcofdoe < acofdoe+NUMBEROFELEMENTINACOFDOE; ++pcofdoe)
+  {
+    if(pcofdoe->NumberOfBits == NumberOfBits && pcofdoe->Bits == Bits)
+      return pcofdoe;
+  }
+  return NULL;
+}
+
+int stCOFDOECompare(const void* pcofdoe1,const void* pcofdoe2)
+{
+  return(EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe1)->u2uod.Value)-
+      EXPONENT(((const struct sCodageOfFrequentDoubleOrExponent *)pcofdoe2)->u2uod.Value));
+}
+
+#ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
+void *memrchr(const void *buf,int c,size_t count)
+{
+  unsigned char
+      *pcBuffer=(unsigned char *)buf,
+                 *pcBufferEnd=pcBuffer-count;
+
+                 for(;pcBuffer>pcBufferEnd;pcBuffer--)
+                   if(*pcBuffer==c)
+                     return(pcBuffer);
+
+                 return(NULL);
+}
+#endif
+#endif
+
+sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE] =
+{
+        {VT_double,2,0x1,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+        {VT_exponent,22,0xd1d32,{DOUBLEWITHTWODWORDINTREE(0x00000000,0x00000000)}},
+        {VT_exponent,22,0xd1d33,{DOUBLEWITHTWODWORDINTREE(0x00100000,0x00000000)}},
+        {VT_exponent,22,0xf78d8,{DOUBLEWITHTWODWORDINTREE(0x00200000,0x00000000)}},
+        {VT_exponent,22,0xf78d9,{DOUBLEWITHTWODWORDINTREE(0x00300000,0x00000000)}},
+        {VT_exponent,22,0xf78da,{DOUBLEWITHTWODWORDINTREE(0x00400000,0x00000000)}},
+        {VT_exponent,22,0xf78db,{DOUBLEWITHTWODWORDINTREE(0x00500000,0x00000000)}},
+        {VT_exponent,22,0xf78dc,{DOUBLEWITHTWODWORDINTREE(0x00600000,0x00000000)}},
+        {VT_exponent,22,0xf78dd,{DOUBLEWITHTWODWORDINTREE(0x00700000,0x00000000)}},
+        {VT_exponent,22,0xf78de,{DOUBLEWITHTWODWORDINTREE(0x00800000,0x00000000)}},
+        {VT_exponent,22,0xf78df,{DOUBLEWITHTWODWORDINTREE(0x00900000,0x00000000)}},
+        {VT_exponent,22,0xf78e0,{DOUBLEWITHTWODWORDINTREE(0x00a00000,0x00000000)}},
+        {VT_exponent,22,0xf78e1,{DOUBLEWITHTWODWORDINTREE(0x00b00000,0x00000000)}},
+        {VT_exponent,22,0xf78e2,{DOUBLEWITHTWODWORDINTREE(0x00c00000,0x00000000)}},
+        {VT_exponent,22,0xf78e3,{DOUBLEWITHTWODWORDINTREE(0x00d00000,0x00000000)}},
+        {VT_exponent,22,0xf78e4,{DOUBLEWITHTWODWORDINTREE(0x00e00000,0x00000000)}},
+        {VT_exponent,22,0xf78e5,{DOUBLEWITHTWODWORDINTREE(0x00f00000,0x00000000)}},
+        {VT_exponent,22,0xf78e6,{DOUBLEWITHTWODWORDINTREE(0x01000000,0x00000000)}},
+        {VT_exponent,22,0xf78e7,{DOUBLEWITHTWODWORDINTREE(0x01100000,0x00000000)}},
+        {VT_exponent,22,0xf78e8,{DOUBLEWITHTWODWORDINTREE(0x01200000,0x00000000)}},
+        {VT_exponent,22,0xf78e9,{DOUBLEWITHTWODWORDINTREE(0x01300000,0x00000000)}},
+        {VT_exponent,22,0xf78ea,{DOUBLEWITHTWODWORDINTREE(0x01400000,0x00000000)}},
+        {VT_exponent,22,0xf78eb,{DOUBLEWITHTWODWORDINTREE(0x01500000,0x00000000)}},
+        {VT_exponent,22,0xf78ec,{DOUBLEWITHTWODWORDINTREE(0x01600000,0x00000000)}},
+        {VT_exponent,22,0xf78ed,{DOUBLEWITHTWODWORDINTREE(0x01700000,0x00000000)}},
+        {VT_exponent,22,0xf78ee,{DOUBLEWITHTWODWORDINTREE(0x01800000,0x00000000)}},
+        {VT_exponent,22,0xf78ef,{DOUBLEWITHTWODWORDINTREE(0x01900000,0x00000000)}},
+        {VT_exponent,22,0xf78f0,{DOUBLEWITHTWODWORDINTREE(0x01a00000,0x00000000)}},
+        {VT_exponent,22,0xf78f1,{DOUBLEWITHTWODWORDINTREE(0x01b00000,0x00000000)}},
+        {VT_exponent,22,0xf78f2,{DOUBLEWITHTWODWORDINTREE(0x01c00000,0x00000000)}},
+        {VT_exponent,22,0xf78f3,{DOUBLEWITHTWODWORDINTREE(0x01d00000,0x00000000)}},
+        {VT_exponent,22,0xf78f4,{DOUBLEWITHTWODWORDINTREE(0x01e00000,0x00000000)}},
+        {VT_exponent,22,0xf78f5,{DOUBLEWITHTWODWORDINTREE(0x01f00000,0x00000000)}},
+        {VT_exponent,22,0xf78f6,{DOUBLEWITHTWODWORDINTREE(0x02000000,0x00000000)}},
+        {VT_exponent,22,0xf78f7,{DOUBLEWITHTWODWORDINTREE(0x02100000,0x00000000)}},
+        {VT_exponent,22,0xf78f8,{DOUBLEWITHTWODWORDINTREE(0x02200000,0x00000000)}},
+        {VT_exponent,22,0xf78f9,{DOUBLEWITHTWODWORDINTREE(0x02300000,0x00000000)}},
+        {VT_exponent,22,0xf78fa,{DOUBLEWITHTWODWORDINTREE(0x02400000,0x00000000)}},
+        {VT_exponent,22,0xf78fb,{DOUBLEWITHTWODWORDINTREE(0x02500000,0x00000000)}},
+        {VT_exponent,22,0xf78fc,{DOUBLEWITHTWODWORDINTREE(0x02600000,0x00000000)}},
+        {VT_exponent,22,0xf78fd,{DOUBLEWITHTWODWORDINTREE(0x02700000,0x00000000)}},
+        {VT_exponent,22,0xf78fe,{DOUBLEWITHTWODWORDINTREE(0x02800000,0x00000000)}},
+        {VT_exponent,22,0xf78ff,{DOUBLEWITHTWODWORDINTREE(0x02900000,0x00000000)}},
+        {VT_exponent,22,0x3a8300,{DOUBLEWITHTWODWORDINTREE(0x02a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8301,{DOUBLEWITHTWODWORDINTREE(0x02b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8302,{DOUBLEWITHTWODWORDINTREE(0x02c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8303,{DOUBLEWITHTWODWORDINTREE(0x02d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8304,{DOUBLEWITHTWODWORDINTREE(0x02e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8305,{DOUBLEWITHTWODWORDINTREE(0x02f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8306,{DOUBLEWITHTWODWORDINTREE(0x03000000,0x00000000)}},
+        {VT_exponent,22,0x3a8307,{DOUBLEWITHTWODWORDINTREE(0x03100000,0x00000000)}},
+        {VT_exponent,22,0x3a8308,{DOUBLEWITHTWODWORDINTREE(0x03200000,0x00000000)}},
+        {VT_exponent,22,0x3a8309,{DOUBLEWITHTWODWORDINTREE(0x03300000,0x00000000)}},
+        {VT_exponent,22,0x3a830a,{DOUBLEWITHTWODWORDINTREE(0x03400000,0x00000000)}},
+        {VT_exponent,22,0x3a830b,{DOUBLEWITHTWODWORDINTREE(0x03500000,0x00000000)}},
+        {VT_exponent,22,0x3a830c,{DOUBLEWITHTWODWORDINTREE(0x03600000,0x00000000)}},
+        {VT_exponent,22,0x3a830d,{DOUBLEWITHTWODWORDINTREE(0x03700000,0x00000000)}},
+        {VT_exponent,22,0x3a830e,{DOUBLEWITHTWODWORDINTREE(0x03800000,0x00000000)}},
+        {VT_exponent,22,0x3a830f,{DOUBLEWITHTWODWORDINTREE(0x03900000,0x00000000)}},
+        {VT_exponent,22,0x3a8310,{DOUBLEWITHTWODWORDINTREE(0x03a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8311,{DOUBLEWITHTWODWORDINTREE(0x03b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8312,{DOUBLEWITHTWODWORDINTREE(0x03c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8313,{DOUBLEWITHTWODWORDINTREE(0x03d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8314,{DOUBLEWITHTWODWORDINTREE(0x03e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8315,{DOUBLEWITHTWODWORDINTREE(0x03f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8316,{DOUBLEWITHTWODWORDINTREE(0x04000000,0x00000000)}},
+        {VT_exponent,22,0x3a8317,{DOUBLEWITHTWODWORDINTREE(0x04100000,0x00000000)}},
+        {VT_exponent,22,0x3a8318,{DOUBLEWITHTWODWORDINTREE(0x04200000,0x00000000)}},
+        {VT_exponent,22,0x3a8319,{DOUBLEWITHTWODWORDINTREE(0x04300000,0x00000000)}},
+        {VT_exponent,22,0x3a831a,{DOUBLEWITHTWODWORDINTREE(0x04400000,0x00000000)}},
+        {VT_exponent,22,0x3a831b,{DOUBLEWITHTWODWORDINTREE(0x04500000,0x00000000)}},
+        {VT_exponent,22,0x3a831c,{DOUBLEWITHTWODWORDINTREE(0x04600000,0x00000000)}},
+        {VT_exponent,22,0x3a831d,{DOUBLEWITHTWODWORDINTREE(0x04700000,0x00000000)}},
+        {VT_exponent,22,0x3a831e,{DOUBLEWITHTWODWORDINTREE(0x04800000,0x00000000)}},
+        {VT_exponent,22,0x3a831f,{DOUBLEWITHTWODWORDINTREE(0x04900000,0x00000000)}},
+        {VT_exponent,22,0x3a8320,{DOUBLEWITHTWODWORDINTREE(0x04a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8321,{DOUBLEWITHTWODWORDINTREE(0x04b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8322,{DOUBLEWITHTWODWORDINTREE(0x04c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8323,{DOUBLEWITHTWODWORDINTREE(0x04d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8324,{DOUBLEWITHTWODWORDINTREE(0x04e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8325,{DOUBLEWITHTWODWORDINTREE(0x04f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8326,{DOUBLEWITHTWODWORDINTREE(0x05000000,0x00000000)}},
+        {VT_exponent,22,0x3a8327,{DOUBLEWITHTWODWORDINTREE(0x05100000,0x00000000)}},
+        {VT_exponent,22,0x3a8328,{DOUBLEWITHTWODWORDINTREE(0x05200000,0x00000000)}},
+        {VT_exponent,22,0x3a8329,{DOUBLEWITHTWODWORDINTREE(0x05300000,0x00000000)}},
+        {VT_exponent,22,0x3a832a,{DOUBLEWITHTWODWORDINTREE(0x05400000,0x00000000)}},
+        {VT_exponent,22,0x3a832b,{DOUBLEWITHTWODWORDINTREE(0x05500000,0x00000000)}},
+        {VT_exponent,22,0x3a832c,{DOUBLEWITHTWODWORDINTREE(0x05600000,0x00000000)}},
+        {VT_exponent,22,0x3a832d,{DOUBLEWITHTWODWORDINTREE(0x05700000,0x00000000)}},
+        {VT_exponent,22,0x3a832e,{DOUBLEWITHTWODWORDINTREE(0x05800000,0x00000000)}},
+        {VT_exponent,22,0x3a832f,{DOUBLEWITHTWODWORDINTREE(0x05900000,0x00000000)}},
+        {VT_exponent,22,0x3a8330,{DOUBLEWITHTWODWORDINTREE(0x05a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8331,{DOUBLEWITHTWODWORDINTREE(0x05b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8332,{DOUBLEWITHTWODWORDINTREE(0x05c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8333,{DOUBLEWITHTWODWORDINTREE(0x05d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8334,{DOUBLEWITHTWODWORDINTREE(0x05e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8335,{DOUBLEWITHTWODWORDINTREE(0x05f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8336,{DOUBLEWITHTWODWORDINTREE(0x06000000,0x00000000)}},
+        {VT_exponent,22,0x3a8337,{DOUBLEWITHTWODWORDINTREE(0x06100000,0x00000000)}},
+        {VT_exponent,22,0x3a8338,{DOUBLEWITHTWODWORDINTREE(0x06200000,0x00000000)}},
+        {VT_exponent,22,0x3a8339,{DOUBLEWITHTWODWORDINTREE(0x06300000,0x00000000)}},
+        {VT_exponent,22,0x3a833a,{DOUBLEWITHTWODWORDINTREE(0x06400000,0x00000000)}},
+        {VT_exponent,22,0x3a833b,{DOUBLEWITHTWODWORDINTREE(0x06500000,0x00000000)}},
+        {VT_exponent,22,0x3a833c,{DOUBLEWITHTWODWORDINTREE(0x06600000,0x00000000)}},
+        {VT_exponent,22,0x3a833d,{DOUBLEWITHTWODWORDINTREE(0x06700000,0x00000000)}},
+        {VT_exponent,22,0x3a833e,{DOUBLEWITHTWODWORDINTREE(0x06800000,0x00000000)}},
+        {VT_exponent,22,0x3a833f,{DOUBLEWITHTWODWORDINTREE(0x06900000,0x00000000)}},
+        {VT_exponent,22,0x3a8340,{DOUBLEWITHTWODWORDINTREE(0x06a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8341,{DOUBLEWITHTWODWORDINTREE(0x06b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8342,{DOUBLEWITHTWODWORDINTREE(0x06c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8343,{DOUBLEWITHTWODWORDINTREE(0x06d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8344,{DOUBLEWITHTWODWORDINTREE(0x06e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8345,{DOUBLEWITHTWODWORDINTREE(0x06f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8346,{DOUBLEWITHTWODWORDINTREE(0x07000000,0x00000000)}},
+        {VT_exponent,22,0x3a8347,{DOUBLEWITHTWODWORDINTREE(0x07100000,0x00000000)}},
+        {VT_exponent,22,0x3a8348,{DOUBLEWITHTWODWORDINTREE(0x07200000,0x00000000)}},
+        {VT_exponent,22,0x3a8349,{DOUBLEWITHTWODWORDINTREE(0x07300000,0x00000000)}},
+        {VT_exponent,22,0x3a834a,{DOUBLEWITHTWODWORDINTREE(0x07400000,0x00000000)}},
+        {VT_exponent,22,0x3a834b,{DOUBLEWITHTWODWORDINTREE(0x07500000,0x00000000)}},
+        {VT_exponent,22,0x3a834c,{DOUBLEWITHTWODWORDINTREE(0x07600000,0x00000000)}},
+        {VT_exponent,22,0x3a834d,{DOUBLEWITHTWODWORDINTREE(0x07700000,0x00000000)}},
+        {VT_exponent,22,0x3a834e,{DOUBLEWITHTWODWORDINTREE(0x07800000,0x00000000)}},
+        {VT_exponent,22,0x3a834f,{DOUBLEWITHTWODWORDINTREE(0x07900000,0x00000000)}},
+        {VT_exponent,22,0x3a8350,{DOUBLEWITHTWODWORDINTREE(0x07a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8351,{DOUBLEWITHTWODWORDINTREE(0x07b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8352,{DOUBLEWITHTWODWORDINTREE(0x07c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8353,{DOUBLEWITHTWODWORDINTREE(0x07d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8354,{DOUBLEWITHTWODWORDINTREE(0x07e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8355,{DOUBLEWITHTWODWORDINTREE(0x07f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8356,{DOUBLEWITHTWODWORDINTREE(0x08000000,0x00000000)}},
+        {VT_exponent,22,0x3a8357,{DOUBLEWITHTWODWORDINTREE(0x08100000,0x00000000)}},
+        {VT_exponent,22,0x3a8358,{DOUBLEWITHTWODWORDINTREE(0x08200000,0x00000000)}},
+        {VT_exponent,22,0x3a8359,{DOUBLEWITHTWODWORDINTREE(0x08300000,0x00000000)}},
+        {VT_exponent,22,0x3a835a,{DOUBLEWITHTWODWORDINTREE(0x08400000,0x00000000)}},
+        {VT_exponent,22,0x3a835b,{DOUBLEWITHTWODWORDINTREE(0x08500000,0x00000000)}},
+        {VT_exponent,22,0x3a835c,{DOUBLEWITHTWODWORDINTREE(0x08600000,0x00000000)}},
+        {VT_exponent,22,0x3a835d,{DOUBLEWITHTWODWORDINTREE(0x08700000,0x00000000)}},
+        {VT_exponent,22,0x3a835e,{DOUBLEWITHTWODWORDINTREE(0x08800000,0x00000000)}},
+        {VT_exponent,22,0x3a835f,{DOUBLEWITHTWODWORDINTREE(0x08900000,0x00000000)}},
+        {VT_exponent,22,0x3a8360,{DOUBLEWITHTWODWORDINTREE(0x08a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8361,{DOUBLEWITHTWODWORDINTREE(0x08b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8362,{DOUBLEWITHTWODWORDINTREE(0x08c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8363,{DOUBLEWITHTWODWORDINTREE(0x08d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8364,{DOUBLEWITHTWODWORDINTREE(0x08e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8365,{DOUBLEWITHTWODWORDINTREE(0x08f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8366,{DOUBLEWITHTWODWORDINTREE(0x09000000,0x00000000)}},
+        {VT_exponent,22,0x3a8367,{DOUBLEWITHTWODWORDINTREE(0x09100000,0x00000000)}},
+        {VT_exponent,22,0x3a8368,{DOUBLEWITHTWODWORDINTREE(0x09200000,0x00000000)}},
+        {VT_exponent,22,0x3a8369,{DOUBLEWITHTWODWORDINTREE(0x09300000,0x00000000)}},
+        {VT_exponent,22,0x3a836a,{DOUBLEWITHTWODWORDINTREE(0x09400000,0x00000000)}},
+        {VT_exponent,22,0x3a836b,{DOUBLEWITHTWODWORDINTREE(0x09500000,0x00000000)}},
+        {VT_exponent,22,0x3a836c,{DOUBLEWITHTWODWORDINTREE(0x09600000,0x00000000)}},
+        {VT_exponent,22,0x3a836d,{DOUBLEWITHTWODWORDINTREE(0x09700000,0x00000000)}},
+        {VT_exponent,22,0x3a836e,{DOUBLEWITHTWODWORDINTREE(0x09800000,0x00000000)}},
+        {VT_exponent,22,0x3a836f,{DOUBLEWITHTWODWORDINTREE(0x09900000,0x00000000)}},
+        {VT_exponent,22,0x3a8370,{DOUBLEWITHTWODWORDINTREE(0x09a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8371,{DOUBLEWITHTWODWORDINTREE(0x09b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8372,{DOUBLEWITHTWODWORDINTREE(0x09c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8373,{DOUBLEWITHTWODWORDINTREE(0x09d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8374,{DOUBLEWITHTWODWORDINTREE(0x09e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8375,{DOUBLEWITHTWODWORDINTREE(0x09f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8376,{DOUBLEWITHTWODWORDINTREE(0x0a000000,0x00000000)}},
+        {VT_exponent,22,0x3a8377,{DOUBLEWITHTWODWORDINTREE(0x0a100000,0x00000000)}},
+        {VT_exponent,22,0x3a8378,{DOUBLEWITHTWODWORDINTREE(0x0a200000,0x00000000)}},
+        {VT_exponent,22,0x3a8379,{DOUBLEWITHTWODWORDINTREE(0x0a300000,0x00000000)}},
+        {VT_exponent,22,0x3a837a,{DOUBLEWITHTWODWORDINTREE(0x0a400000,0x00000000)}},
+        {VT_exponent,22,0x3a837b,{DOUBLEWITHTWODWORDINTREE(0x0a500000,0x00000000)}},
+        {VT_exponent,22,0x3a837c,{DOUBLEWITHTWODWORDINTREE(0x0a600000,0x00000000)}},
+        {VT_exponent,22,0x3a837d,{DOUBLEWITHTWODWORDINTREE(0x0a700000,0x00000000)}},
+        {VT_exponent,22,0x3a837e,{DOUBLEWITHTWODWORDINTREE(0x0a800000,0x00000000)}},
+        {VT_exponent,22,0x3a837f,{DOUBLEWITHTWODWORDINTREE(0x0a900000,0x00000000)}},
+        {VT_exponent,22,0x3a8380,{DOUBLEWITHTWODWORDINTREE(0x0aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a8381,{DOUBLEWITHTWODWORDINTREE(0x0ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a8382,{DOUBLEWITHTWODWORDINTREE(0x0ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a8383,{DOUBLEWITHTWODWORDINTREE(0x0ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a8384,{DOUBLEWITHTWODWORDINTREE(0x0ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a8385,{DOUBLEWITHTWODWORDINTREE(0x0af00000,0x00000000)}},
+        {VT_exponent,22,0x3a8386,{DOUBLEWITHTWODWORDINTREE(0x0b000000,0x00000000)}},
+        {VT_exponent,22,0x3a8387,{DOUBLEWITHTWODWORDINTREE(0x0b100000,0x00000000)}},
+        {VT_exponent,22,0x3a8388,{DOUBLEWITHTWODWORDINTREE(0x0b200000,0x00000000)}},
+        {VT_exponent,22,0x3a8389,{DOUBLEWITHTWODWORDINTREE(0x0b300000,0x00000000)}},
+        {VT_exponent,22,0x3a838a,{DOUBLEWITHTWODWORDINTREE(0x0b400000,0x00000000)}},
+        {VT_exponent,22,0x3a838b,{DOUBLEWITHTWODWORDINTREE(0x0b500000,0x00000000)}},
+        {VT_exponent,22,0x3a838c,{DOUBLEWITHTWODWORDINTREE(0x0b600000,0x00000000)}},
+        {VT_exponent,22,0x3a838d,{DOUBLEWITHTWODWORDINTREE(0x0b700000,0x00000000)}},
+        {VT_exponent,22,0x3a838e,{DOUBLEWITHTWODWORDINTREE(0x0b800000,0x00000000)}},
+        {VT_exponent,22,0x3a838f,{DOUBLEWITHTWODWORDINTREE(0x0b900000,0x00000000)}},
+        {VT_exponent,22,0x3a8390,{DOUBLEWITHTWODWORDINTREE(0x0ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a8391,{DOUBLEWITHTWODWORDINTREE(0x0bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a8392,{DOUBLEWITHTWODWORDINTREE(0x0bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a8393,{DOUBLEWITHTWODWORDINTREE(0x0bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a8394,{DOUBLEWITHTWODWORDINTREE(0x0be00000,0x00000000)}},
+        {VT_exponent,22,0x3a8395,{DOUBLEWITHTWODWORDINTREE(0x0bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a8396,{DOUBLEWITHTWODWORDINTREE(0x0c000000,0x00000000)}},
+        {VT_exponent,22,0x3a8397,{DOUBLEWITHTWODWORDINTREE(0x0c100000,0x00000000)}},
+        {VT_exponent,22,0x3a8398,{DOUBLEWITHTWODWORDINTREE(0x0c200000,0x00000000)}},
+        {VT_exponent,22,0x3a8399,{DOUBLEWITHTWODWORDINTREE(0x0c300000,0x00000000)}},
+        {VT_exponent,22,0x3a839a,{DOUBLEWITHTWODWORDINTREE(0x0c400000,0x00000000)}},
+        {VT_exponent,22,0x3a839b,{DOUBLEWITHTWODWORDINTREE(0x0c500000,0x00000000)}},
+        {VT_exponent,22,0x3a839c,{DOUBLEWITHTWODWORDINTREE(0x0c600000,0x00000000)}},
+        {VT_exponent,22,0x3a839d,{DOUBLEWITHTWODWORDINTREE(0x0c700000,0x00000000)}},
+        {VT_exponent,22,0x3a839e,{DOUBLEWITHTWODWORDINTREE(0x0c800000,0x00000000)}},
+        {VT_exponent,22,0x3a839f,{DOUBLEWITHTWODWORDINTREE(0x0c900000,0x00000000)}},
+        {VT_exponent,22,0x3a83a0,{DOUBLEWITHTWODWORDINTREE(0x0ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a1,{DOUBLEWITHTWODWORDINTREE(0x0cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a2,{DOUBLEWITHTWODWORDINTREE(0x0cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a3,{DOUBLEWITHTWODWORDINTREE(0x0cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a4,{DOUBLEWITHTWODWORDINTREE(0x0ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a5,{DOUBLEWITHTWODWORDINTREE(0x0cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a83a6,{DOUBLEWITHTWODWORDINTREE(0x0d000000,0x00000000)}},
+        {VT_exponent,22,0x3a83a7,{DOUBLEWITHTWODWORDINTREE(0x0d100000,0x00000000)}},
+        {VT_exponent,22,0x3a83a8,{DOUBLEWITHTWODWORDINTREE(0x0d200000,0x00000000)}},
+        {VT_exponent,22,0x3a83a9,{DOUBLEWITHTWODWORDINTREE(0x0d300000,0x00000000)}},
+        {VT_exponent,22,0x3a83aa,{DOUBLEWITHTWODWORDINTREE(0x0d400000,0x00000000)}},
+        {VT_exponent,22,0x3a83ab,{DOUBLEWITHTWODWORDINTREE(0x0d500000,0x00000000)}},
+        {VT_exponent,22,0x3a83ac,{DOUBLEWITHTWODWORDINTREE(0x0d600000,0x00000000)}},
+        {VT_exponent,22,0x3a83ad,{DOUBLEWITHTWODWORDINTREE(0x0d700000,0x00000000)}},
+        {VT_exponent,22,0x3a83ae,{DOUBLEWITHTWODWORDINTREE(0x0d800000,0x00000000)}},
+        {VT_exponent,22,0x3a83af,{DOUBLEWITHTWODWORDINTREE(0x0d900000,0x00000000)}},
+        {VT_exponent,22,0x3a83b0,{DOUBLEWITHTWODWORDINTREE(0x0da00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b1,{DOUBLEWITHTWODWORDINTREE(0x0db00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b2,{DOUBLEWITHTWODWORDINTREE(0x0dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b3,{DOUBLEWITHTWODWORDINTREE(0x0dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b4,{DOUBLEWITHTWODWORDINTREE(0x0de00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b5,{DOUBLEWITHTWODWORDINTREE(0x0df00000,0x00000000)}},
+        {VT_exponent,22,0x3a83b6,{DOUBLEWITHTWODWORDINTREE(0x0e000000,0x00000000)}},
+        {VT_exponent,22,0x3a83b7,{DOUBLEWITHTWODWORDINTREE(0x0e100000,0x00000000)}},
+        {VT_exponent,22,0x3a83b8,{DOUBLEWITHTWODWORDINTREE(0x0e200000,0x00000000)}},
+        {VT_exponent,22,0x3a83b9,{DOUBLEWITHTWODWORDINTREE(0x0e300000,0x00000000)}},
+        {VT_exponent,22,0x3a83ba,{DOUBLEWITHTWODWORDINTREE(0x0e400000,0x00000000)}},
+        {VT_exponent,22,0x3a83bb,{DOUBLEWITHTWODWORDINTREE(0x0e500000,0x00000000)}},
+        {VT_exponent,22,0x3a83bc,{DOUBLEWITHTWODWORDINTREE(0x0e600000,0x00000000)}},
+        {VT_exponent,22,0x3a83bd,{DOUBLEWITHTWODWORDINTREE(0x0e700000,0x00000000)}},
+        {VT_exponent,22,0x3a83be,{DOUBLEWITHTWODWORDINTREE(0x0e800000,0x00000000)}},
+        {VT_exponent,22,0x3a83bf,{DOUBLEWITHTWODWORDINTREE(0x0e900000,0x00000000)}},
+        {VT_exponent,22,0x3a83c0,{DOUBLEWITHTWODWORDINTREE(0x0ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c1,{DOUBLEWITHTWODWORDINTREE(0x0eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c2,{DOUBLEWITHTWODWORDINTREE(0x0ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c3,{DOUBLEWITHTWODWORDINTREE(0x0ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c4,{DOUBLEWITHTWODWORDINTREE(0x0ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c5,{DOUBLEWITHTWODWORDINTREE(0x0ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a83c6,{DOUBLEWITHTWODWORDINTREE(0x0f000000,0x00000000)}},
+        {VT_exponent,22,0x3a83c7,{DOUBLEWITHTWODWORDINTREE(0x0f100000,0x00000000)}},
+        {VT_exponent,22,0x3a83c8,{DOUBLEWITHTWODWORDINTREE(0x0f200000,0x00000000)}},
+        {VT_exponent,22,0x3a83c9,{DOUBLEWITHTWODWORDINTREE(0x0f300000,0x00000000)}},
+        {VT_exponent,22,0x3a83ca,{DOUBLEWITHTWODWORDINTREE(0x0f400000,0x00000000)}},
+        {VT_exponent,22,0x3a83cb,{DOUBLEWITHTWODWORDINTREE(0x0f500000,0x00000000)}},
+        {VT_exponent,22,0x3a83cc,{DOUBLEWITHTWODWORDINTREE(0x0f600000,0x00000000)}},
+        {VT_exponent,22,0x3a83cd,{DOUBLEWITHTWODWORDINTREE(0x0f700000,0x00000000)}},
+        {VT_exponent,22,0x3a83ce,{DOUBLEWITHTWODWORDINTREE(0x0f800000,0x00000000)}},
+        {VT_exponent,22,0x3a83cf,{DOUBLEWITHTWODWORDINTREE(0x0f900000,0x00000000)}},
+        {VT_exponent,22,0x3a83d0,{DOUBLEWITHTWODWORDINTREE(0x0fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d1,{DOUBLEWITHTWODWORDINTREE(0x0fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d2,{DOUBLEWITHTWODWORDINTREE(0x0fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d3,{DOUBLEWITHTWODWORDINTREE(0x0fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d4,{DOUBLEWITHTWODWORDINTREE(0x0fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d5,{DOUBLEWITHTWODWORDINTREE(0x0ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a83d6,{DOUBLEWITHTWODWORDINTREE(0x10000000,0x00000000)}},
+        {VT_exponent,22,0x3a83d7,{DOUBLEWITHTWODWORDINTREE(0x10100000,0x00000000)}},
+        {VT_exponent,22,0x3a83d8,{DOUBLEWITHTWODWORDINTREE(0x10200000,0x00000000)}},
+        {VT_exponent,22,0x3a83d9,{DOUBLEWITHTWODWORDINTREE(0x10300000,0x00000000)}},
+        {VT_exponent,22,0x3a83da,{DOUBLEWITHTWODWORDINTREE(0x10400000,0x00000000)}},
+        {VT_exponent,22,0x3a83db,{DOUBLEWITHTWODWORDINTREE(0x10500000,0x00000000)}},
+        {VT_exponent,22,0x3a83dc,{DOUBLEWITHTWODWORDINTREE(0x10600000,0x00000000)}},
+        {VT_exponent,22,0x3a83dd,{DOUBLEWITHTWODWORDINTREE(0x10700000,0x00000000)}},
+        {VT_exponent,22,0x3a83de,{DOUBLEWITHTWODWORDINTREE(0x10800000,0x00000000)}},
+        {VT_exponent,22,0x3a83df,{DOUBLEWITHTWODWORDINTREE(0x10900000,0x00000000)}},
+        {VT_exponent,22,0x3a83e0,{DOUBLEWITHTWODWORDINTREE(0x10a00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e1,{DOUBLEWITHTWODWORDINTREE(0x10b00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e2,{DOUBLEWITHTWODWORDINTREE(0x10c00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e3,{DOUBLEWITHTWODWORDINTREE(0x10d00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e4,{DOUBLEWITHTWODWORDINTREE(0x10e00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e5,{DOUBLEWITHTWODWORDINTREE(0x10f00000,0x00000000)}},
+        {VT_exponent,22,0x3a83e6,{DOUBLEWITHTWODWORDINTREE(0x11000000,0x00000000)}},
+        {VT_exponent,22,0x3a83e7,{DOUBLEWITHTWODWORDINTREE(0x11100000,0x00000000)}},
+        {VT_exponent,22,0x3a83e8,{DOUBLEWITHTWODWORDINTREE(0x11200000,0x00000000)}},
+        {VT_exponent,22,0x3a83e9,{DOUBLEWITHTWODWORDINTREE(0x11300000,0x00000000)}},
+        {VT_exponent,22,0x3a83ea,{DOUBLEWITHTWODWORDINTREE(0x11400000,0x00000000)}},
+        {VT_exponent,22,0x3a83eb,{DOUBLEWITHTWODWORDINTREE(0x11500000,0x00000000)}},
+        {VT_exponent,22,0x3a83ec,{DOUBLEWITHTWODWORDINTREE(0x11600000,0x00000000)}},
+        {VT_exponent,22,0x3a83ed,{DOUBLEWITHTWODWORDINTREE(0x11700000,0x00000000)}},
+        {VT_exponent,22,0x3a83ee,{DOUBLEWITHTWODWORDINTREE(0x11800000,0x00000000)}},
+        {VT_exponent,22,0x3a83ef,{DOUBLEWITHTWODWORDINTREE(0x11900000,0x00000000)}},
+        {VT_exponent,22,0x3a83f0,{DOUBLEWITHTWODWORDINTREE(0x11a00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f1,{DOUBLEWITHTWODWORDINTREE(0x11b00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f2,{DOUBLEWITHTWODWORDINTREE(0x11c00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f3,{DOUBLEWITHTWODWORDINTREE(0x11d00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f4,{DOUBLEWITHTWODWORDINTREE(0x11e00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f5,{DOUBLEWITHTWODWORDINTREE(0x11f00000,0x00000000)}},
+        {VT_exponent,22,0x3a83f6,{DOUBLEWITHTWODWORDINTREE(0x12000000,0x00000000)}},
+        {VT_exponent,22,0x3a83f7,{DOUBLEWITHTWODWORDINTREE(0x12100000,0x00000000)}},
+        {VT_exponent,22,0x3a83f8,{DOUBLEWITHTWODWORDINTREE(0x12200000,0x00000000)}},
+        {VT_exponent,22,0x3a83f9,{DOUBLEWITHTWODWORDINTREE(0x12300000,0x00000000)}},
+        {VT_exponent,22,0x3a83fa,{DOUBLEWITHTWODWORDINTREE(0x12400000,0x00000000)}},
+        {VT_exponent,22,0x3a83fb,{DOUBLEWITHTWODWORDINTREE(0x12500000,0x00000000)}},
+        {VT_exponent,22,0x3a83fc,{DOUBLEWITHTWODWORDINTREE(0x12600000,0x00000000)}},
+        {VT_exponent,22,0x3a83fd,{DOUBLEWITHTWODWORDINTREE(0x12700000,0x00000000)}},
+        {VT_exponent,22,0x3a83fe,{DOUBLEWITHTWODWORDINTREE(0x12800000,0x00000000)}},
+        {VT_exponent,22,0x3a83ff,{DOUBLEWITHTWODWORDINTREE(0x12900000,0x00000000)}},
+        {VT_exponent,22,0x3a8400,{DOUBLEWITHTWODWORDINTREE(0x12a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8401,{DOUBLEWITHTWODWORDINTREE(0x12b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8402,{DOUBLEWITHTWODWORDINTREE(0x12c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8403,{DOUBLEWITHTWODWORDINTREE(0x12d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8404,{DOUBLEWITHTWODWORDINTREE(0x12e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8405,{DOUBLEWITHTWODWORDINTREE(0x12f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8406,{DOUBLEWITHTWODWORDINTREE(0x13000000,0x00000000)}},
+        {VT_exponent,22,0x3a8407,{DOUBLEWITHTWODWORDINTREE(0x13100000,0x00000000)}},
+        {VT_exponent,22,0x3a8408,{DOUBLEWITHTWODWORDINTREE(0x13200000,0x00000000)}},
+        {VT_exponent,22,0x3a8409,{DOUBLEWITHTWODWORDINTREE(0x13300000,0x00000000)}},
+        {VT_exponent,22,0x3a840a,{DOUBLEWITHTWODWORDINTREE(0x13400000,0x00000000)}},
+        {VT_exponent,22,0x3a840b,{DOUBLEWITHTWODWORDINTREE(0x13500000,0x00000000)}},
+        {VT_exponent,22,0x3a840c,{DOUBLEWITHTWODWORDINTREE(0x13600000,0x00000000)}},
+        {VT_exponent,22,0x3a840d,{DOUBLEWITHTWODWORDINTREE(0x13700000,0x00000000)}},
+        {VT_exponent,22,0x3a840e,{DOUBLEWITHTWODWORDINTREE(0x13800000,0x00000000)}},
+        {VT_exponent,22,0x3a840f,{DOUBLEWITHTWODWORDINTREE(0x13900000,0x00000000)}},
+        {VT_exponent,22,0x3a8410,{DOUBLEWITHTWODWORDINTREE(0x13a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8411,{DOUBLEWITHTWODWORDINTREE(0x13b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8412,{DOUBLEWITHTWODWORDINTREE(0x13c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8413,{DOUBLEWITHTWODWORDINTREE(0x13d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8414,{DOUBLEWITHTWODWORDINTREE(0x13e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8415,{DOUBLEWITHTWODWORDINTREE(0x13f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8416,{DOUBLEWITHTWODWORDINTREE(0x14000000,0x00000000)}},
+        {VT_exponent,22,0x3a8417,{DOUBLEWITHTWODWORDINTREE(0x14100000,0x00000000)}},
+        {VT_exponent,22,0x3a8418,{DOUBLEWITHTWODWORDINTREE(0x14200000,0x00000000)}},
+        {VT_exponent,22,0x3a8419,{DOUBLEWITHTWODWORDINTREE(0x14300000,0x00000000)}},
+        {VT_exponent,22,0x3a841a,{DOUBLEWITHTWODWORDINTREE(0x14400000,0x00000000)}},
+        {VT_exponent,22,0x3a841b,{DOUBLEWITHTWODWORDINTREE(0x14500000,0x00000000)}},
+        {VT_exponent,22,0x3a841c,{DOUBLEWITHTWODWORDINTREE(0x14600000,0x00000000)}},
+        {VT_exponent,22,0x3a841d,{DOUBLEWITHTWODWORDINTREE(0x14700000,0x00000000)}},
+        {VT_exponent,22,0x3a841e,{DOUBLEWITHTWODWORDINTREE(0x14800000,0x00000000)}},
+        {VT_exponent,22,0x3a841f,{DOUBLEWITHTWODWORDINTREE(0x14900000,0x00000000)}},
+        {VT_exponent,22,0x3a8420,{DOUBLEWITHTWODWORDINTREE(0x14a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8421,{DOUBLEWITHTWODWORDINTREE(0x14b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8422,{DOUBLEWITHTWODWORDINTREE(0x14c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8423,{DOUBLEWITHTWODWORDINTREE(0x14d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8424,{DOUBLEWITHTWODWORDINTREE(0x14e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8425,{DOUBLEWITHTWODWORDINTREE(0x14f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8426,{DOUBLEWITHTWODWORDINTREE(0x15000000,0x00000000)}},
+        {VT_exponent,22,0x3a8427,{DOUBLEWITHTWODWORDINTREE(0x15100000,0x00000000)}},
+        {VT_exponent,22,0x3a8428,{DOUBLEWITHTWODWORDINTREE(0x15200000,0x00000000)}},
+        {VT_exponent,22,0x3a8429,{DOUBLEWITHTWODWORDINTREE(0x15300000,0x00000000)}},
+        {VT_exponent,22,0x3a842a,{DOUBLEWITHTWODWORDINTREE(0x15400000,0x00000000)}},
+        {VT_exponent,22,0x3a842b,{DOUBLEWITHTWODWORDINTREE(0x15500000,0x00000000)}},
+        {VT_exponent,22,0x3a842c,{DOUBLEWITHTWODWORDINTREE(0x15600000,0x00000000)}},
+        {VT_exponent,22,0x3a842d,{DOUBLEWITHTWODWORDINTREE(0x15700000,0x00000000)}},
+        {VT_exponent,22,0x3a842e,{DOUBLEWITHTWODWORDINTREE(0x15800000,0x00000000)}},
+        {VT_exponent,22,0x3a842f,{DOUBLEWITHTWODWORDINTREE(0x15900000,0x00000000)}},
+        {VT_exponent,22,0x3a8430,{DOUBLEWITHTWODWORDINTREE(0x15a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8431,{DOUBLEWITHTWODWORDINTREE(0x15b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8432,{DOUBLEWITHTWODWORDINTREE(0x15c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8433,{DOUBLEWITHTWODWORDINTREE(0x15d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8434,{DOUBLEWITHTWODWORDINTREE(0x15e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8435,{DOUBLEWITHTWODWORDINTREE(0x15f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8436,{DOUBLEWITHTWODWORDINTREE(0x16000000,0x00000000)}},
+        {VT_exponent,22,0x3a8437,{DOUBLEWITHTWODWORDINTREE(0x16100000,0x00000000)}},
+        {VT_exponent,22,0x3a8438,{DOUBLEWITHTWODWORDINTREE(0x16200000,0x00000000)}},
+        {VT_exponent,22,0x3a8439,{DOUBLEWITHTWODWORDINTREE(0x16300000,0x00000000)}},
+        {VT_exponent,22,0x3a843a,{DOUBLEWITHTWODWORDINTREE(0x16400000,0x00000000)}},
+        {VT_exponent,22,0x3a843b,{DOUBLEWITHTWODWORDINTREE(0x16500000,0x00000000)}},
+        {VT_exponent,22,0x3a843c,{DOUBLEWITHTWODWORDINTREE(0x16600000,0x00000000)}},
+        {VT_exponent,22,0x3a843d,{DOUBLEWITHTWODWORDINTREE(0x16700000,0x00000000)}},
+        {VT_exponent,22,0x3a843e,{DOUBLEWITHTWODWORDINTREE(0x16800000,0x00000000)}},
+        {VT_exponent,22,0x3a843f,{DOUBLEWITHTWODWORDINTREE(0x16900000,0x00000000)}},
+        {VT_exponent,22,0x3a8440,{DOUBLEWITHTWODWORDINTREE(0x16a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8441,{DOUBLEWITHTWODWORDINTREE(0x16b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8442,{DOUBLEWITHTWODWORDINTREE(0x16c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8443,{DOUBLEWITHTWODWORDINTREE(0x16d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8444,{DOUBLEWITHTWODWORDINTREE(0x16e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8445,{DOUBLEWITHTWODWORDINTREE(0x16f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8446,{DOUBLEWITHTWODWORDINTREE(0x17000000,0x00000000)}},
+        {VT_exponent,22,0x3a8447,{DOUBLEWITHTWODWORDINTREE(0x17100000,0x00000000)}},
+        {VT_exponent,22,0x3a8448,{DOUBLEWITHTWODWORDINTREE(0x17200000,0x00000000)}},
+        {VT_exponent,22,0x3a8449,{DOUBLEWITHTWODWORDINTREE(0x17300000,0x00000000)}},
+        {VT_exponent,22,0x3a844a,{DOUBLEWITHTWODWORDINTREE(0x17400000,0x00000000)}},
+        {VT_exponent,22,0x3a844b,{DOUBLEWITHTWODWORDINTREE(0x17500000,0x00000000)}},
+        {VT_exponent,22,0x3a844c,{DOUBLEWITHTWODWORDINTREE(0x17600000,0x00000000)}},
+        {VT_exponent,22,0x3a844d,{DOUBLEWITHTWODWORDINTREE(0x17700000,0x00000000)}},
+        {VT_exponent,22,0x3a844e,{DOUBLEWITHTWODWORDINTREE(0x17800000,0x00000000)}},
+        {VT_exponent,22,0x3a844f,{DOUBLEWITHTWODWORDINTREE(0x17900000,0x00000000)}},
+        {VT_exponent,22,0x3a8450,{DOUBLEWITHTWODWORDINTREE(0x17a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8451,{DOUBLEWITHTWODWORDINTREE(0x17b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8452,{DOUBLEWITHTWODWORDINTREE(0x17c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8453,{DOUBLEWITHTWODWORDINTREE(0x17d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8454,{DOUBLEWITHTWODWORDINTREE(0x17e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8455,{DOUBLEWITHTWODWORDINTREE(0x17f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8456,{DOUBLEWITHTWODWORDINTREE(0x18000000,0x00000000)}},
+        {VT_exponent,22,0x3a8457,{DOUBLEWITHTWODWORDINTREE(0x18100000,0x00000000)}},
+        {VT_exponent,22,0x3a8458,{DOUBLEWITHTWODWORDINTREE(0x18200000,0x00000000)}},
+        {VT_exponent,22,0x3a8459,{DOUBLEWITHTWODWORDINTREE(0x18300000,0x00000000)}},
+        {VT_exponent,22,0x3a845a,{DOUBLEWITHTWODWORDINTREE(0x18400000,0x00000000)}},
+        {VT_exponent,22,0x3a845b,{DOUBLEWITHTWODWORDINTREE(0x18500000,0x00000000)}},
+        {VT_exponent,22,0x3a845c,{DOUBLEWITHTWODWORDINTREE(0x18600000,0x00000000)}},
+        {VT_exponent,22,0x3a845d,{DOUBLEWITHTWODWORDINTREE(0x18700000,0x00000000)}},
+        {VT_exponent,22,0x3a845e,{DOUBLEWITHTWODWORDINTREE(0x18800000,0x00000000)}},
+        {VT_exponent,22,0x3a845f,{DOUBLEWITHTWODWORDINTREE(0x18900000,0x00000000)}},
+        {VT_exponent,22,0x3a8460,{DOUBLEWITHTWODWORDINTREE(0x18a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8461,{DOUBLEWITHTWODWORDINTREE(0x18b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8462,{DOUBLEWITHTWODWORDINTREE(0x18c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8463,{DOUBLEWITHTWODWORDINTREE(0x18d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8464,{DOUBLEWITHTWODWORDINTREE(0x18e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8465,{DOUBLEWITHTWODWORDINTREE(0x18f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8466,{DOUBLEWITHTWODWORDINTREE(0x19000000,0x00000000)}},
+        {VT_exponent,22,0x3a8467,{DOUBLEWITHTWODWORDINTREE(0x19100000,0x00000000)}},
+        {VT_exponent,22,0x3a8468,{DOUBLEWITHTWODWORDINTREE(0x19200000,0x00000000)}},
+        {VT_exponent,22,0x3a8469,{DOUBLEWITHTWODWORDINTREE(0x19300000,0x00000000)}},
+        {VT_exponent,22,0x3a846a,{DOUBLEWITHTWODWORDINTREE(0x19400000,0x00000000)}},
+        {VT_exponent,22,0x3a846b,{DOUBLEWITHTWODWORDINTREE(0x19500000,0x00000000)}},
+        {VT_exponent,22,0x3a846c,{DOUBLEWITHTWODWORDINTREE(0x19600000,0x00000000)}},
+        {VT_exponent,22,0x3a846d,{DOUBLEWITHTWODWORDINTREE(0x19700000,0x00000000)}},
+        {VT_exponent,22,0x3a846e,{DOUBLEWITHTWODWORDINTREE(0x19800000,0x00000000)}},
+        {VT_exponent,22,0x3a846f,{DOUBLEWITHTWODWORDINTREE(0x19900000,0x00000000)}},
+        {VT_exponent,22,0x3a8470,{DOUBLEWITHTWODWORDINTREE(0x19a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8471,{DOUBLEWITHTWODWORDINTREE(0x19b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8472,{DOUBLEWITHTWODWORDINTREE(0x19c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8473,{DOUBLEWITHTWODWORDINTREE(0x19d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8474,{DOUBLEWITHTWODWORDINTREE(0x19e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8475,{DOUBLEWITHTWODWORDINTREE(0x19f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8476,{DOUBLEWITHTWODWORDINTREE(0x1a000000,0x00000000)}},
+        {VT_exponent,22,0x3a8477,{DOUBLEWITHTWODWORDINTREE(0x1a100000,0x00000000)}},
+        {VT_exponent,22,0x3a8478,{DOUBLEWITHTWODWORDINTREE(0x1a200000,0x00000000)}},
+        {VT_exponent,22,0x3a8479,{DOUBLEWITHTWODWORDINTREE(0x1a300000,0x00000000)}},
+        {VT_exponent,22,0x3a847a,{DOUBLEWITHTWODWORDINTREE(0x1a400000,0x00000000)}},
+        {VT_exponent,22,0x3a847b,{DOUBLEWITHTWODWORDINTREE(0x1a500000,0x00000000)}},
+        {VT_exponent,22,0x3a847c,{DOUBLEWITHTWODWORDINTREE(0x1a600000,0x00000000)}},
+        {VT_exponent,22,0x3a847d,{DOUBLEWITHTWODWORDINTREE(0x1a700000,0x00000000)}},
+        {VT_exponent,22,0x3a847e,{DOUBLEWITHTWODWORDINTREE(0x1a800000,0x00000000)}},
+        {VT_exponent,22,0x3a847f,{DOUBLEWITHTWODWORDINTREE(0x1a900000,0x00000000)}},
+        {VT_exponent,22,0x3a8480,{DOUBLEWITHTWODWORDINTREE(0x1aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a8481,{DOUBLEWITHTWODWORDINTREE(0x1ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a8482,{DOUBLEWITHTWODWORDINTREE(0x1ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a8483,{DOUBLEWITHTWODWORDINTREE(0x1ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a8484,{DOUBLEWITHTWODWORDINTREE(0x1ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a8485,{DOUBLEWITHTWODWORDINTREE(0x1af00000,0x00000000)}},
+        {VT_exponent,22,0x3a8486,{DOUBLEWITHTWODWORDINTREE(0x1b000000,0x00000000)}},
+        {VT_exponent,22,0x3a8487,{DOUBLEWITHTWODWORDINTREE(0x1b100000,0x00000000)}},
+        {VT_exponent,22,0x3a8488,{DOUBLEWITHTWODWORDINTREE(0x1b200000,0x00000000)}},
+        {VT_exponent,22,0x3a8489,{DOUBLEWITHTWODWORDINTREE(0x1b300000,0x00000000)}},
+        {VT_exponent,22,0x3a848a,{DOUBLEWITHTWODWORDINTREE(0x1b400000,0x00000000)}},
+        {VT_exponent,22,0x3a848b,{DOUBLEWITHTWODWORDINTREE(0x1b500000,0x00000000)}},
+        {VT_exponent,22,0x3a848c,{DOUBLEWITHTWODWORDINTREE(0x1b600000,0x00000000)}},
+        {VT_exponent,22,0x3a848d,{DOUBLEWITHTWODWORDINTREE(0x1b700000,0x00000000)}},
+        {VT_exponent,22,0x3a848e,{DOUBLEWITHTWODWORDINTREE(0x1b800000,0x00000000)}},
+        {VT_exponent,22,0x3a848f,{DOUBLEWITHTWODWORDINTREE(0x1b900000,0x00000000)}},
+        {VT_exponent,22,0x3a8490,{DOUBLEWITHTWODWORDINTREE(0x1ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a8491,{DOUBLEWITHTWODWORDINTREE(0x1bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a8492,{DOUBLEWITHTWODWORDINTREE(0x1bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a8493,{DOUBLEWITHTWODWORDINTREE(0x1bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a8494,{DOUBLEWITHTWODWORDINTREE(0x1be00000,0x00000000)}},
+        {VT_exponent,22,0x3a8495,{DOUBLEWITHTWODWORDINTREE(0x1bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a8496,{DOUBLEWITHTWODWORDINTREE(0x1c000000,0x00000000)}},
+        {VT_exponent,22,0x3a8497,{DOUBLEWITHTWODWORDINTREE(0x1c100000,0x00000000)}},
+        {VT_exponent,22,0x3a8498,{DOUBLEWITHTWODWORDINTREE(0x1c200000,0x00000000)}},
+        {VT_exponent,22,0x3a8499,{DOUBLEWITHTWODWORDINTREE(0x1c300000,0x00000000)}},
+        {VT_exponent,22,0x3a849a,{DOUBLEWITHTWODWORDINTREE(0x1c400000,0x00000000)}},
+        {VT_exponent,22,0x3a849b,{DOUBLEWITHTWODWORDINTREE(0x1c500000,0x00000000)}},
+        {VT_exponent,22,0x3a849c,{DOUBLEWITHTWODWORDINTREE(0x1c600000,0x00000000)}},
+        {VT_exponent,22,0x3a849d,{DOUBLEWITHTWODWORDINTREE(0x1c700000,0x00000000)}},
+        {VT_exponent,22,0x3a849e,{DOUBLEWITHTWODWORDINTREE(0x1c800000,0x00000000)}},
+        {VT_exponent,22,0x3a849f,{DOUBLEWITHTWODWORDINTREE(0x1c900000,0x00000000)}},
+        {VT_exponent,22,0x3a84a0,{DOUBLEWITHTWODWORDINTREE(0x1ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a1,{DOUBLEWITHTWODWORDINTREE(0x1cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a2,{DOUBLEWITHTWODWORDINTREE(0x1cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a3,{DOUBLEWITHTWODWORDINTREE(0x1cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a4,{DOUBLEWITHTWODWORDINTREE(0x1ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a5,{DOUBLEWITHTWODWORDINTREE(0x1cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a84a6,{DOUBLEWITHTWODWORDINTREE(0x1d000000,0x00000000)}},
+        {VT_exponent,22,0x3a84a7,{DOUBLEWITHTWODWORDINTREE(0x1d100000,0x00000000)}},
+        {VT_exponent,22,0x3a84a8,{DOUBLEWITHTWODWORDINTREE(0x1d200000,0x00000000)}},
+        {VT_exponent,22,0x3a84a9,{DOUBLEWITHTWODWORDINTREE(0x1d300000,0x00000000)}},
+        {VT_exponent,22,0x3a84aa,{DOUBLEWITHTWODWORDINTREE(0x1d400000,0x00000000)}},
+        {VT_exponent,22,0x3a84ab,{DOUBLEWITHTWODWORDINTREE(0x1d500000,0x00000000)}},
+        {VT_exponent,22,0x3a84ac,{DOUBLEWITHTWODWORDINTREE(0x1d600000,0x00000000)}},
+        {VT_exponent,22,0x3a84ad,{DOUBLEWITHTWODWORDINTREE(0x1d700000,0x00000000)}},
+        {VT_exponent,22,0x3a84ae,{DOUBLEWITHTWODWORDINTREE(0x1d800000,0x00000000)}},
+        {VT_exponent,22,0x3a84af,{DOUBLEWITHTWODWORDINTREE(0x1d900000,0x00000000)}},
+        {VT_exponent,22,0x3a84b0,{DOUBLEWITHTWODWORDINTREE(0x1da00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b1,{DOUBLEWITHTWODWORDINTREE(0x1db00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b2,{DOUBLEWITHTWODWORDINTREE(0x1dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b3,{DOUBLEWITHTWODWORDINTREE(0x1dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b4,{DOUBLEWITHTWODWORDINTREE(0x1de00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b5,{DOUBLEWITHTWODWORDINTREE(0x1df00000,0x00000000)}},
+        {VT_exponent,22,0x3a84b6,{DOUBLEWITHTWODWORDINTREE(0x1e000000,0x00000000)}},
+        {VT_exponent,22,0x3a84b7,{DOUBLEWITHTWODWORDINTREE(0x1e100000,0x00000000)}},
+        {VT_exponent,22,0x3a84b8,{DOUBLEWITHTWODWORDINTREE(0x1e200000,0x00000000)}},
+        {VT_exponent,22,0x3a84b9,{DOUBLEWITHTWODWORDINTREE(0x1e300000,0x00000000)}},
+        {VT_exponent,22,0x3a84ba,{DOUBLEWITHTWODWORDINTREE(0x1e400000,0x00000000)}},
+        {VT_exponent,22,0x3a84bb,{DOUBLEWITHTWODWORDINTREE(0x1e500000,0x00000000)}},
+        {VT_exponent,22,0x3a84bc,{DOUBLEWITHTWODWORDINTREE(0x1e600000,0x00000000)}},
+        {VT_exponent,22,0x3a84bd,{DOUBLEWITHTWODWORDINTREE(0x1e700000,0x00000000)}},
+        {VT_exponent,22,0x3a84be,{DOUBLEWITHTWODWORDINTREE(0x1e800000,0x00000000)}},
+        {VT_exponent,22,0x3a84bf,{DOUBLEWITHTWODWORDINTREE(0x1e900000,0x00000000)}},
+        {VT_exponent,22,0x3a84c0,{DOUBLEWITHTWODWORDINTREE(0x1ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c1,{DOUBLEWITHTWODWORDINTREE(0x1eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c2,{DOUBLEWITHTWODWORDINTREE(0x1ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c3,{DOUBLEWITHTWODWORDINTREE(0x1ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c4,{DOUBLEWITHTWODWORDINTREE(0x1ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c5,{DOUBLEWITHTWODWORDINTREE(0x1ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a84c6,{DOUBLEWITHTWODWORDINTREE(0x1f000000,0x00000000)}},
+        {VT_exponent,22,0x3a84c7,{DOUBLEWITHTWODWORDINTREE(0x1f100000,0x00000000)}},
+        {VT_exponent,22,0x3a84c8,{DOUBLEWITHTWODWORDINTREE(0x1f200000,0x00000000)}},
+        {VT_exponent,22,0x3a84c9,{DOUBLEWITHTWODWORDINTREE(0x1f300000,0x00000000)}},
+        {VT_exponent,22,0x3a84ca,{DOUBLEWITHTWODWORDINTREE(0x1f400000,0x00000000)}},
+        {VT_exponent,22,0x3a84cb,{DOUBLEWITHTWODWORDINTREE(0x1f500000,0x00000000)}},
+        {VT_exponent,22,0x3a84cc,{DOUBLEWITHTWODWORDINTREE(0x1f600000,0x00000000)}},
+        {VT_exponent,22,0x3a84cd,{DOUBLEWITHTWODWORDINTREE(0x1f700000,0x00000000)}},
+        {VT_exponent,22,0x3a84ce,{DOUBLEWITHTWODWORDINTREE(0x1f800000,0x00000000)}},
+        {VT_exponent,22,0x3a84cf,{DOUBLEWITHTWODWORDINTREE(0x1f900000,0x00000000)}},
+        {VT_exponent,22,0x3a84d0,{DOUBLEWITHTWODWORDINTREE(0x1fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d1,{DOUBLEWITHTWODWORDINTREE(0x1fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d2,{DOUBLEWITHTWODWORDINTREE(0x1fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d3,{DOUBLEWITHTWODWORDINTREE(0x1fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d4,{DOUBLEWITHTWODWORDINTREE(0x1fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d5,{DOUBLEWITHTWODWORDINTREE(0x1ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a84d6,{DOUBLEWITHTWODWORDINTREE(0x20000000,0x00000000)}},
+        {VT_exponent,22,0x3a84d7,{DOUBLEWITHTWODWORDINTREE(0x20100000,0x00000000)}},
+        {VT_exponent,22,0x3a84d8,{DOUBLEWITHTWODWORDINTREE(0x20200000,0x00000000)}},
+        {VT_exponent,22,0x3a84d9,{DOUBLEWITHTWODWORDINTREE(0x20300000,0x00000000)}},
+        {VT_exponent,22,0x3a84da,{DOUBLEWITHTWODWORDINTREE(0x20400000,0x00000000)}},
+        {VT_exponent,22,0x3a84db,{DOUBLEWITHTWODWORDINTREE(0x20500000,0x00000000)}},
+        {VT_exponent,22,0x3a84dc,{DOUBLEWITHTWODWORDINTREE(0x20600000,0x00000000)}},
+        {VT_exponent,22,0x3a84dd,{DOUBLEWITHTWODWORDINTREE(0x20700000,0x00000000)}},
+        {VT_exponent,22,0x3a84de,{DOUBLEWITHTWODWORDINTREE(0x20800000,0x00000000)}},
+        {VT_exponent,22,0x3a84df,{DOUBLEWITHTWODWORDINTREE(0x20900000,0x00000000)}},
+        {VT_exponent,22,0x3a84e0,{DOUBLEWITHTWODWORDINTREE(0x20a00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e1,{DOUBLEWITHTWODWORDINTREE(0x20b00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e2,{DOUBLEWITHTWODWORDINTREE(0x20c00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e3,{DOUBLEWITHTWODWORDINTREE(0x20d00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e4,{DOUBLEWITHTWODWORDINTREE(0x20e00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e5,{DOUBLEWITHTWODWORDINTREE(0x20f00000,0x00000000)}},
+        {VT_exponent,22,0x3a84e6,{DOUBLEWITHTWODWORDINTREE(0x21000000,0x00000000)}},
+        {VT_exponent,22,0x3a84e7,{DOUBLEWITHTWODWORDINTREE(0x21100000,0x00000000)}},
+        {VT_exponent,22,0x3a84e8,{DOUBLEWITHTWODWORDINTREE(0x21200000,0x00000000)}},
+        {VT_exponent,22,0x3a84e9,{DOUBLEWITHTWODWORDINTREE(0x21300000,0x00000000)}},
+        {VT_exponent,22,0x3a84ea,{DOUBLEWITHTWODWORDINTREE(0x21400000,0x00000000)}},
+        {VT_exponent,22,0x3a84eb,{DOUBLEWITHTWODWORDINTREE(0x21500000,0x00000000)}},
+        {VT_exponent,22,0x3a84ec,{DOUBLEWITHTWODWORDINTREE(0x21600000,0x00000000)}},
+        {VT_exponent,22,0x3a84ed,{DOUBLEWITHTWODWORDINTREE(0x21700000,0x00000000)}},
+        {VT_exponent,22,0x3a84ee,{DOUBLEWITHTWODWORDINTREE(0x21800000,0x00000000)}},
+        {VT_exponent,22,0x3a84ef,{DOUBLEWITHTWODWORDINTREE(0x21900000,0x00000000)}},
+        {VT_exponent,22,0x3a84f0,{DOUBLEWITHTWODWORDINTREE(0x21a00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f1,{DOUBLEWITHTWODWORDINTREE(0x21b00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f2,{DOUBLEWITHTWODWORDINTREE(0x21c00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f3,{DOUBLEWITHTWODWORDINTREE(0x21d00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f4,{DOUBLEWITHTWODWORDINTREE(0x21e00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f5,{DOUBLEWITHTWODWORDINTREE(0x21f00000,0x00000000)}},
+        {VT_exponent,22,0x3a84f6,{DOUBLEWITHTWODWORDINTREE(0x22000000,0x00000000)}},
+        {VT_exponent,22,0x3a84f7,{DOUBLEWITHTWODWORDINTREE(0x22100000,0x00000000)}},
+        {VT_exponent,22,0x3a84f8,{DOUBLEWITHTWODWORDINTREE(0x22200000,0x00000000)}},
+        {VT_exponent,22,0x3a84f9,{DOUBLEWITHTWODWORDINTREE(0x22300000,0x00000000)}},
+        {VT_exponent,22,0x3a84fa,{DOUBLEWITHTWODWORDINTREE(0x22400000,0x00000000)}},
+        {VT_exponent,22,0x3a84fb,{DOUBLEWITHTWODWORDINTREE(0x22500000,0x00000000)}},
+        {VT_exponent,22,0x3a84fc,{DOUBLEWITHTWODWORDINTREE(0x22600000,0x00000000)}},
+        {VT_exponent,22,0x3a84fd,{DOUBLEWITHTWODWORDINTREE(0x22700000,0x00000000)}},
+        {VT_exponent,22,0x3a84fe,{DOUBLEWITHTWODWORDINTREE(0x22800000,0x00000000)}},
+        {VT_exponent,22,0x3a84ff,{DOUBLEWITHTWODWORDINTREE(0x22900000,0x00000000)}},
+        {VT_exponent,22,0x3a8500,{DOUBLEWITHTWODWORDINTREE(0x22a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8501,{DOUBLEWITHTWODWORDINTREE(0x22b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8502,{DOUBLEWITHTWODWORDINTREE(0x22c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8503,{DOUBLEWITHTWODWORDINTREE(0x22d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8504,{DOUBLEWITHTWODWORDINTREE(0x22e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8505,{DOUBLEWITHTWODWORDINTREE(0x22f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8506,{DOUBLEWITHTWODWORDINTREE(0x23000000,0x00000000)}},
+        {VT_exponent,22,0x3a8507,{DOUBLEWITHTWODWORDINTREE(0x23100000,0x00000000)}},
+        {VT_exponent,22,0x3a8508,{DOUBLEWITHTWODWORDINTREE(0x23200000,0x00000000)}},
+        {VT_exponent,22,0x3a8509,{DOUBLEWITHTWODWORDINTREE(0x23300000,0x00000000)}},
+        {VT_exponent,22,0x3a850a,{DOUBLEWITHTWODWORDINTREE(0x23400000,0x00000000)}},
+        {VT_exponent,22,0x3a850b,{DOUBLEWITHTWODWORDINTREE(0x23500000,0x00000000)}},
+        {VT_exponent,22,0x3a850c,{DOUBLEWITHTWODWORDINTREE(0x23600000,0x00000000)}},
+        {VT_exponent,22,0x3a850d,{DOUBLEWITHTWODWORDINTREE(0x23700000,0x00000000)}},
+        {VT_exponent,22,0x3a850e,{DOUBLEWITHTWODWORDINTREE(0x23800000,0x00000000)}},
+        {VT_exponent,22,0x3a850f,{DOUBLEWITHTWODWORDINTREE(0x23900000,0x00000000)}},
+        {VT_exponent,22,0x3a8510,{DOUBLEWITHTWODWORDINTREE(0x23a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8511,{DOUBLEWITHTWODWORDINTREE(0x23b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8512,{DOUBLEWITHTWODWORDINTREE(0x23c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8513,{DOUBLEWITHTWODWORDINTREE(0x23d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8514,{DOUBLEWITHTWODWORDINTREE(0x23e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8515,{DOUBLEWITHTWODWORDINTREE(0x23f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8516,{DOUBLEWITHTWODWORDINTREE(0x24000000,0x00000000)}},
+        {VT_exponent,22,0x3a8517,{DOUBLEWITHTWODWORDINTREE(0x24100000,0x00000000)}},
+        {VT_exponent,22,0x3a8518,{DOUBLEWITHTWODWORDINTREE(0x24200000,0x00000000)}},
+        {VT_exponent,22,0x3a8519,{DOUBLEWITHTWODWORDINTREE(0x24300000,0x00000000)}},
+        {VT_exponent,22,0x3a851a,{DOUBLEWITHTWODWORDINTREE(0x24400000,0x00000000)}},
+        {VT_exponent,22,0x3a851b,{DOUBLEWITHTWODWORDINTREE(0x24500000,0x00000000)}},
+        {VT_exponent,22,0x3a851c,{DOUBLEWITHTWODWORDINTREE(0x24600000,0x00000000)}},
+        {VT_exponent,22,0x3a851d,{DOUBLEWITHTWODWORDINTREE(0x24700000,0x00000000)}},
+        {VT_exponent,22,0x3a851e,{DOUBLEWITHTWODWORDINTREE(0x24800000,0x00000000)}},
+        {VT_exponent,22,0x3a851f,{DOUBLEWITHTWODWORDINTREE(0x24900000,0x00000000)}},
+        {VT_exponent,22,0x3a8520,{DOUBLEWITHTWODWORDINTREE(0x24a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8521,{DOUBLEWITHTWODWORDINTREE(0x24b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8522,{DOUBLEWITHTWODWORDINTREE(0x24c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8523,{DOUBLEWITHTWODWORDINTREE(0x24d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8524,{DOUBLEWITHTWODWORDINTREE(0x24e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8525,{DOUBLEWITHTWODWORDINTREE(0x24f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8526,{DOUBLEWITHTWODWORDINTREE(0x25000000,0x00000000)}},
+        {VT_exponent,22,0x3a8527,{DOUBLEWITHTWODWORDINTREE(0x25100000,0x00000000)}},
+        {VT_exponent,22,0x3a8528,{DOUBLEWITHTWODWORDINTREE(0x25200000,0x00000000)}},
+        {VT_exponent,22,0x3a8529,{DOUBLEWITHTWODWORDINTREE(0x25300000,0x00000000)}},
+        {VT_exponent,22,0x3a852a,{DOUBLEWITHTWODWORDINTREE(0x25400000,0x00000000)}},
+        {VT_exponent,22,0x3a852b,{DOUBLEWITHTWODWORDINTREE(0x25500000,0x00000000)}},
+        {VT_exponent,22,0x3a852c,{DOUBLEWITHTWODWORDINTREE(0x25600000,0x00000000)}},
+        {VT_exponent,22,0x3a852d,{DOUBLEWITHTWODWORDINTREE(0x25700000,0x00000000)}},
+        {VT_exponent,22,0x3a852e,{DOUBLEWITHTWODWORDINTREE(0x25800000,0x00000000)}},
+        {VT_exponent,22,0x3a852f,{DOUBLEWITHTWODWORDINTREE(0x25900000,0x00000000)}},
+        {VT_exponent,22,0x3a8530,{DOUBLEWITHTWODWORDINTREE(0x25a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8531,{DOUBLEWITHTWODWORDINTREE(0x25b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8532,{DOUBLEWITHTWODWORDINTREE(0x25c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8533,{DOUBLEWITHTWODWORDINTREE(0x25d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8534,{DOUBLEWITHTWODWORDINTREE(0x25e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8535,{DOUBLEWITHTWODWORDINTREE(0x25f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8536,{DOUBLEWITHTWODWORDINTREE(0x26000000,0x00000000)}},
+        {VT_exponent,22,0x3a8537,{DOUBLEWITHTWODWORDINTREE(0x26100000,0x00000000)}},
+        {VT_exponent,22,0x3a8538,{DOUBLEWITHTWODWORDINTREE(0x26200000,0x00000000)}},
+        {VT_exponent,22,0x3a8539,{DOUBLEWITHTWODWORDINTREE(0x26300000,0x00000000)}},
+        {VT_exponent,22,0x3a853a,{DOUBLEWITHTWODWORDINTREE(0x26400000,0x00000000)}},
+        {VT_exponent,22,0x3a853b,{DOUBLEWITHTWODWORDINTREE(0x26500000,0x00000000)}},
+        {VT_exponent,22,0x3a853c,{DOUBLEWITHTWODWORDINTREE(0x26600000,0x00000000)}},
+        {VT_exponent,22,0x3a853d,{DOUBLEWITHTWODWORDINTREE(0x26700000,0x00000000)}},
+        {VT_exponent,22,0x3a853e,{DOUBLEWITHTWODWORDINTREE(0x26800000,0x00000000)}},
+        {VT_exponent,22,0x3a853f,{DOUBLEWITHTWODWORDINTREE(0x26900000,0x00000000)}},
+        {VT_exponent,22,0x3a8540,{DOUBLEWITHTWODWORDINTREE(0x26a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8541,{DOUBLEWITHTWODWORDINTREE(0x26b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8542,{DOUBLEWITHTWODWORDINTREE(0x26c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8543,{DOUBLEWITHTWODWORDINTREE(0x26d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8544,{DOUBLEWITHTWODWORDINTREE(0x26e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8545,{DOUBLEWITHTWODWORDINTREE(0x26f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8546,{DOUBLEWITHTWODWORDINTREE(0x27000000,0x00000000)}},
+        {VT_exponent,22,0x3a8547,{DOUBLEWITHTWODWORDINTREE(0x27100000,0x00000000)}},
+        {VT_exponent,22,0x3a8548,{DOUBLEWITHTWODWORDINTREE(0x27200000,0x00000000)}},
+        {VT_exponent,22,0x3a8549,{DOUBLEWITHTWODWORDINTREE(0x27300000,0x00000000)}},
+        {VT_exponent,22,0x3a854a,{DOUBLEWITHTWODWORDINTREE(0x27400000,0x00000000)}},
+        {VT_exponent,22,0x3a854b,{DOUBLEWITHTWODWORDINTREE(0x27500000,0x00000000)}},
+        {VT_exponent,22,0x3a854c,{DOUBLEWITHTWODWORDINTREE(0x27600000,0x00000000)}},
+        {VT_exponent,22,0x3a854d,{DOUBLEWITHTWODWORDINTREE(0x27700000,0x00000000)}},
+        {VT_exponent,22,0x3a854e,{DOUBLEWITHTWODWORDINTREE(0x27800000,0x00000000)}},
+        {VT_exponent,22,0x3a854f,{DOUBLEWITHTWODWORDINTREE(0x27900000,0x00000000)}},
+        {VT_exponent,22,0x3a8550,{DOUBLEWITHTWODWORDINTREE(0x27a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8551,{DOUBLEWITHTWODWORDINTREE(0x27b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8552,{DOUBLEWITHTWODWORDINTREE(0x27c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8553,{DOUBLEWITHTWODWORDINTREE(0x27d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8554,{DOUBLEWITHTWODWORDINTREE(0x27e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8555,{DOUBLEWITHTWODWORDINTREE(0x27f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8556,{DOUBLEWITHTWODWORDINTREE(0x28000000,0x00000000)}},
+        {VT_exponent,22,0x3a8557,{DOUBLEWITHTWODWORDINTREE(0x28100000,0x00000000)}},
+        {VT_exponent,22,0x3a8558,{DOUBLEWITHTWODWORDINTREE(0x28200000,0x00000000)}},
+        {VT_exponent,22,0x3a8559,{DOUBLEWITHTWODWORDINTREE(0x28300000,0x00000000)}},
+        {VT_exponent,22,0x3a855a,{DOUBLEWITHTWODWORDINTREE(0x28400000,0x00000000)}},
+        {VT_exponent,22,0x3a855b,{DOUBLEWITHTWODWORDINTREE(0x28500000,0x00000000)}},
+        {VT_exponent,22,0x3a855c,{DOUBLEWITHTWODWORDINTREE(0x28600000,0x00000000)}},
+        {VT_exponent,22,0x3a855d,{DOUBLEWITHTWODWORDINTREE(0x28700000,0x00000000)}},
+        {VT_exponent,22,0x3a855e,{DOUBLEWITHTWODWORDINTREE(0x28800000,0x00000000)}},
+        {VT_exponent,22,0x3a855f,{DOUBLEWITHTWODWORDINTREE(0x28900000,0x00000000)}},
+        {VT_exponent,22,0x3a8560,{DOUBLEWITHTWODWORDINTREE(0x28a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8561,{DOUBLEWITHTWODWORDINTREE(0x28b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8562,{DOUBLEWITHTWODWORDINTREE(0x28c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8563,{DOUBLEWITHTWODWORDINTREE(0x28d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8564,{DOUBLEWITHTWODWORDINTREE(0x28e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8565,{DOUBLEWITHTWODWORDINTREE(0x28f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8566,{DOUBLEWITHTWODWORDINTREE(0x29000000,0x00000000)}},
+        {VT_exponent,22,0x3a8567,{DOUBLEWITHTWODWORDINTREE(0x29100000,0x00000000)}},
+        {VT_exponent,22,0x3a8568,{DOUBLEWITHTWODWORDINTREE(0x29200000,0x00000000)}},
+        {VT_exponent,22,0x3a8569,{DOUBLEWITHTWODWORDINTREE(0x29300000,0x00000000)}},
+        {VT_exponent,22,0x3a856a,{DOUBLEWITHTWODWORDINTREE(0x29400000,0x00000000)}},
+        {VT_exponent,22,0x3a856b,{DOUBLEWITHTWODWORDINTREE(0x29500000,0x00000000)}},
+        {VT_exponent,22,0x3a856c,{DOUBLEWITHTWODWORDINTREE(0x29600000,0x00000000)}},
+        {VT_exponent,22,0x3a856d,{DOUBLEWITHTWODWORDINTREE(0x29700000,0x00000000)}},
+        {VT_exponent,22,0x3a856e,{DOUBLEWITHTWODWORDINTREE(0x29800000,0x00000000)}},
+        {VT_exponent,22,0x3a856f,{DOUBLEWITHTWODWORDINTREE(0x29900000,0x00000000)}},
+        {VT_exponent,22,0x3a8570,{DOUBLEWITHTWODWORDINTREE(0x29a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8571,{DOUBLEWITHTWODWORDINTREE(0x29b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8572,{DOUBLEWITHTWODWORDINTREE(0x29c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8573,{DOUBLEWITHTWODWORDINTREE(0x29d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8574,{DOUBLEWITHTWODWORDINTREE(0x29e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8575,{DOUBLEWITHTWODWORDINTREE(0x29f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8576,{DOUBLEWITHTWODWORDINTREE(0x2a000000,0x00000000)}},
+        {VT_exponent,22,0x3a8577,{DOUBLEWITHTWODWORDINTREE(0x2a100000,0x00000000)}},
+        {VT_exponent,22,0x3a8578,{DOUBLEWITHTWODWORDINTREE(0x2a200000,0x00000000)}},
+        {VT_exponent,22,0x3a8579,{DOUBLEWITHTWODWORDINTREE(0x2a300000,0x00000000)}},
+        {VT_exponent,22,0x3a857a,{DOUBLEWITHTWODWORDINTREE(0x2a400000,0x00000000)}},
+        {VT_exponent,22,0x3a857b,{DOUBLEWITHTWODWORDINTREE(0x2a500000,0x00000000)}},
+        {VT_exponent,22,0x3a857c,{DOUBLEWITHTWODWORDINTREE(0x2a600000,0x00000000)}},
+        {VT_exponent,22,0x3a857d,{DOUBLEWITHTWODWORDINTREE(0x2a700000,0x00000000)}},
+        {VT_exponent,22,0x3a857e,{DOUBLEWITHTWODWORDINTREE(0x2a800000,0x00000000)}},
+        {VT_exponent,22,0x3a857f,{DOUBLEWITHTWODWORDINTREE(0x2a900000,0x00000000)}},
+        {VT_exponent,22,0x3a8580,{DOUBLEWITHTWODWORDINTREE(0x2aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a8581,{DOUBLEWITHTWODWORDINTREE(0x2ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a8582,{DOUBLEWITHTWODWORDINTREE(0x2ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a8583,{DOUBLEWITHTWODWORDINTREE(0x2ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a8584,{DOUBLEWITHTWODWORDINTREE(0x2ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a8585,{DOUBLEWITHTWODWORDINTREE(0x2af00000,0x00000000)}},
+        {VT_exponent,22,0x3a8586,{DOUBLEWITHTWODWORDINTREE(0x2b000000,0x00000000)}},
+        {VT_exponent,22,0x3a8587,{DOUBLEWITHTWODWORDINTREE(0x2b100000,0x00000000)}},
+        {VT_exponent,22,0x3a8588,{DOUBLEWITHTWODWORDINTREE(0x2b200000,0x00000000)}},
+        {VT_exponent,22,0x3a8589,{DOUBLEWITHTWODWORDINTREE(0x2b300000,0x00000000)}},
+        {VT_exponent,22,0x3a858a,{DOUBLEWITHTWODWORDINTREE(0x2b400000,0x00000000)}},
+        {VT_exponent,22,0x3a858b,{DOUBLEWITHTWODWORDINTREE(0x2b500000,0x00000000)}},
+        {VT_exponent,22,0x3a858c,{DOUBLEWITHTWODWORDINTREE(0x2b600000,0x00000000)}},
+        {VT_exponent,22,0x3a858d,{DOUBLEWITHTWODWORDINTREE(0x2b700000,0x00000000)}},
+        {VT_exponent,22,0x3a858e,{DOUBLEWITHTWODWORDINTREE(0x2b800000,0x00000000)}},
+        {VT_exponent,22,0x3a858f,{DOUBLEWITHTWODWORDINTREE(0x2b900000,0x00000000)}},
+        {VT_exponent,22,0x3a8590,{DOUBLEWITHTWODWORDINTREE(0x2ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a8591,{DOUBLEWITHTWODWORDINTREE(0x2bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a8592,{DOUBLEWITHTWODWORDINTREE(0x2bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a8593,{DOUBLEWITHTWODWORDINTREE(0x2bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a8594,{DOUBLEWITHTWODWORDINTREE(0x2be00000,0x00000000)}},
+        {VT_exponent,22,0x3a8595,{DOUBLEWITHTWODWORDINTREE(0x2bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a8596,{DOUBLEWITHTWODWORDINTREE(0x2c000000,0x00000000)}},
+        {VT_exponent,22,0x3a8597,{DOUBLEWITHTWODWORDINTREE(0x2c100000,0x00000000)}},
+        {VT_exponent,22,0x3a8598,{DOUBLEWITHTWODWORDINTREE(0x2c200000,0x00000000)}},
+        {VT_exponent,22,0x3a8599,{DOUBLEWITHTWODWORDINTREE(0x2c300000,0x00000000)}},
+        {VT_exponent,22,0x3a859a,{DOUBLEWITHTWODWORDINTREE(0x2c400000,0x00000000)}},
+        {VT_exponent,22,0x3a859b,{DOUBLEWITHTWODWORDINTREE(0x2c500000,0x00000000)}},
+        {VT_exponent,22,0x3a859c,{DOUBLEWITHTWODWORDINTREE(0x2c600000,0x00000000)}},
+        {VT_exponent,22,0x3a859d,{DOUBLEWITHTWODWORDINTREE(0x2c700000,0x00000000)}},
+        {VT_exponent,22,0x3a859e,{DOUBLEWITHTWODWORDINTREE(0x2c800000,0x00000000)}},
+        {VT_exponent,22,0x3a859f,{DOUBLEWITHTWODWORDINTREE(0x2c900000,0x00000000)}},
+        {VT_exponent,22,0x3a85a0,{DOUBLEWITHTWODWORDINTREE(0x2ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a1,{DOUBLEWITHTWODWORDINTREE(0x2cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a2,{DOUBLEWITHTWODWORDINTREE(0x2cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a3,{DOUBLEWITHTWODWORDINTREE(0x2cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a4,{DOUBLEWITHTWODWORDINTREE(0x2ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a5,{DOUBLEWITHTWODWORDINTREE(0x2cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a85a6,{DOUBLEWITHTWODWORDINTREE(0x2d000000,0x00000000)}},
+        {VT_exponent,22,0x3a85a7,{DOUBLEWITHTWODWORDINTREE(0x2d100000,0x00000000)}},
+        {VT_exponent,22,0x3a85a8,{DOUBLEWITHTWODWORDINTREE(0x2d200000,0x00000000)}},
+        {VT_exponent,22,0x3a85a9,{DOUBLEWITHTWODWORDINTREE(0x2d300000,0x00000000)}},
+        {VT_exponent,22,0x3a85aa,{DOUBLEWITHTWODWORDINTREE(0x2d400000,0x00000000)}},
+        {VT_exponent,22,0x3a85ab,{DOUBLEWITHTWODWORDINTREE(0x2d500000,0x00000000)}},
+        {VT_exponent,22,0x3a85ac,{DOUBLEWITHTWODWORDINTREE(0x2d600000,0x00000000)}},
+        {VT_exponent,22,0x3a85ad,{DOUBLEWITHTWODWORDINTREE(0x2d700000,0x00000000)}},
+        {VT_exponent,22,0x3a85ae,{DOUBLEWITHTWODWORDINTREE(0x2d800000,0x00000000)}},
+        {VT_exponent,22,0x3a85af,{DOUBLEWITHTWODWORDINTREE(0x2d900000,0x00000000)}},
+        {VT_exponent,22,0x3a85b0,{DOUBLEWITHTWODWORDINTREE(0x2da00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b1,{DOUBLEWITHTWODWORDINTREE(0x2db00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b2,{DOUBLEWITHTWODWORDINTREE(0x2dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b3,{DOUBLEWITHTWODWORDINTREE(0x2dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b4,{DOUBLEWITHTWODWORDINTREE(0x2de00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b5,{DOUBLEWITHTWODWORDINTREE(0x2df00000,0x00000000)}},
+        {VT_exponent,22,0x3a85b6,{DOUBLEWITHTWODWORDINTREE(0x2e000000,0x00000000)}},
+        {VT_exponent,22,0x3a85b7,{DOUBLEWITHTWODWORDINTREE(0x2e100000,0x00000000)}},
+        {VT_exponent,22,0x3a85b8,{DOUBLEWITHTWODWORDINTREE(0x2e200000,0x00000000)}},
+        {VT_exponent,22,0x3a85b9,{DOUBLEWITHTWODWORDINTREE(0x2e300000,0x00000000)}},
+        {VT_exponent,22,0x3a85ba,{DOUBLEWITHTWODWORDINTREE(0x2e400000,0x00000000)}},
+        {VT_exponent,22,0x3a85bb,{DOUBLEWITHTWODWORDINTREE(0x2e500000,0x00000000)}},
+        {VT_exponent,22,0x3a85bc,{DOUBLEWITHTWODWORDINTREE(0x2e600000,0x00000000)}},
+        {VT_exponent,22,0x3a85bd,{DOUBLEWITHTWODWORDINTREE(0x2e700000,0x00000000)}},
+        {VT_exponent,22,0x3a85be,{DOUBLEWITHTWODWORDINTREE(0x2e800000,0x00000000)}},
+        {VT_exponent,22,0x3a85bf,{DOUBLEWITHTWODWORDINTREE(0x2e900000,0x00000000)}},
+        {VT_exponent,22,0x3a85c0,{DOUBLEWITHTWODWORDINTREE(0x2ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c1,{DOUBLEWITHTWODWORDINTREE(0x2eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c2,{DOUBLEWITHTWODWORDINTREE(0x2ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c3,{DOUBLEWITHTWODWORDINTREE(0x2ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c4,{DOUBLEWITHTWODWORDINTREE(0x2ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c5,{DOUBLEWITHTWODWORDINTREE(0x2ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a85c6,{DOUBLEWITHTWODWORDINTREE(0x2f000000,0x00000000)}},
+        {VT_exponent,22,0x3a85c7,{DOUBLEWITHTWODWORDINTREE(0x2f100000,0x00000000)}},
+        {VT_exponent,22,0x3a85c8,{DOUBLEWITHTWODWORDINTREE(0x2f200000,0x00000000)}},
+        {VT_exponent,22,0x3a85c9,{DOUBLEWITHTWODWORDINTREE(0x2f300000,0x00000000)}},
+        {VT_exponent,22,0x3a85ca,{DOUBLEWITHTWODWORDINTREE(0x2f400000,0x00000000)}},
+        {VT_exponent,22,0x3a85cb,{DOUBLEWITHTWODWORDINTREE(0x2f500000,0x00000000)}},
+        {VT_exponent,22,0x3a85cc,{DOUBLEWITHTWODWORDINTREE(0x2f600000,0x00000000)}},
+        {VT_exponent,22,0x3a85cd,{DOUBLEWITHTWODWORDINTREE(0x2f700000,0x00000000)}},
+        {VT_exponent,22,0x3a85ce,{DOUBLEWITHTWODWORDINTREE(0x2f800000,0x00000000)}},
+        {VT_exponent,22,0x3a85cf,{DOUBLEWITHTWODWORDINTREE(0x2f900000,0x00000000)}},
+        {VT_exponent,22,0x3a85d0,{DOUBLEWITHTWODWORDINTREE(0x2fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d1,{DOUBLEWITHTWODWORDINTREE(0x2fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d2,{DOUBLEWITHTWODWORDINTREE(0x2fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d3,{DOUBLEWITHTWODWORDINTREE(0x2fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d4,{DOUBLEWITHTWODWORDINTREE(0x2fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d5,{DOUBLEWITHTWODWORDINTREE(0x2ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a85d6,{DOUBLEWITHTWODWORDINTREE(0x30000000,0x00000000)}},
+        {VT_exponent,22,0x3a85d7,{DOUBLEWITHTWODWORDINTREE(0x30100000,0x00000000)}},
+        {VT_exponent,22,0x3a85d8,{DOUBLEWITHTWODWORDINTREE(0x30200000,0x00000000)}},
+        {VT_exponent,22,0x3a85d9,{DOUBLEWITHTWODWORDINTREE(0x30300000,0x00000000)}},
+        {VT_exponent,22,0x3a85da,{DOUBLEWITHTWODWORDINTREE(0x30400000,0x00000000)}},
+        {VT_exponent,22,0x3a85db,{DOUBLEWITHTWODWORDINTREE(0x30500000,0x00000000)}},
+        {VT_exponent,22,0x3a85dc,{DOUBLEWITHTWODWORDINTREE(0x30600000,0x00000000)}},
+        {VT_exponent,22,0x3a85dd,{DOUBLEWITHTWODWORDINTREE(0x30700000,0x00000000)}},
+        {VT_exponent,22,0x3a85de,{DOUBLEWITHTWODWORDINTREE(0x30800000,0x00000000)}},
+        {VT_exponent,22,0x3a85df,{DOUBLEWITHTWODWORDINTREE(0x30900000,0x00000000)}},
+        {VT_exponent,22,0x3a85e0,{DOUBLEWITHTWODWORDINTREE(0x30a00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e1,{DOUBLEWITHTWODWORDINTREE(0x30b00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e2,{DOUBLEWITHTWODWORDINTREE(0x30c00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e3,{DOUBLEWITHTWODWORDINTREE(0x30d00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e4,{DOUBLEWITHTWODWORDINTREE(0x30e00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e5,{DOUBLEWITHTWODWORDINTREE(0x30f00000,0x00000000)}},
+        {VT_exponent,22,0x3a85e6,{DOUBLEWITHTWODWORDINTREE(0x31000000,0x00000000)}},
+        {VT_exponent,22,0x3a85e7,{DOUBLEWITHTWODWORDINTREE(0x31100000,0x00000000)}},
+        {VT_exponent,22,0x3a85e8,{DOUBLEWITHTWODWORDINTREE(0x31200000,0x00000000)}},
+        {VT_exponent,22,0x3a85e9,{DOUBLEWITHTWODWORDINTREE(0x31300000,0x00000000)}},
+        {VT_exponent,22,0x3a85ea,{DOUBLEWITHTWODWORDINTREE(0x31400000,0x00000000)}},
+        {VT_exponent,22,0x3a85eb,{DOUBLEWITHTWODWORDINTREE(0x31500000,0x00000000)}},
+        {VT_exponent,22,0x3a85ec,{DOUBLEWITHTWODWORDINTREE(0x31600000,0x00000000)}},
+        {VT_exponent,22,0x3a85ed,{DOUBLEWITHTWODWORDINTREE(0x31700000,0x00000000)}},
+        {VT_exponent,22,0x3a85ee,{DOUBLEWITHTWODWORDINTREE(0x31800000,0x00000000)}},
+        {VT_exponent,22,0x3a85ef,{DOUBLEWITHTWODWORDINTREE(0x31900000,0x00000000)}},
+        {VT_exponent,22,0x3a85f0,{DOUBLEWITHTWODWORDINTREE(0x31a00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f1,{DOUBLEWITHTWODWORDINTREE(0x31b00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f2,{DOUBLEWITHTWODWORDINTREE(0x31c00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f3,{DOUBLEWITHTWODWORDINTREE(0x31d00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f4,{DOUBLEWITHTWODWORDINTREE(0x31e00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f5,{DOUBLEWITHTWODWORDINTREE(0x31f00000,0x00000000)}},
+        {VT_exponent,22,0x3a85f6,{DOUBLEWITHTWODWORDINTREE(0x32000000,0x00000000)}},
+        {VT_exponent,22,0x3a85f7,{DOUBLEWITHTWODWORDINTREE(0x32100000,0x00000000)}},
+        {VT_exponent,22,0x3a85f8,{DOUBLEWITHTWODWORDINTREE(0x32200000,0x00000000)}},
+        {VT_exponent,22,0x3a85f9,{DOUBLEWITHTWODWORDINTREE(0x32300000,0x00000000)}},
+        {VT_exponent,22,0x3a85fa,{DOUBLEWITHTWODWORDINTREE(0x32400000,0x00000000)}},
+        {VT_exponent,22,0x3a85fb,{DOUBLEWITHTWODWORDINTREE(0x32500000,0x00000000)}},
+        {VT_exponent,22,0x3a85fc,{DOUBLEWITHTWODWORDINTREE(0x32600000,0x00000000)}},
+        {VT_exponent,22,0x3a85fd,{DOUBLEWITHTWODWORDINTREE(0x32700000,0x00000000)}},
+        {VT_exponent,22,0x3a85fe,{DOUBLEWITHTWODWORDINTREE(0x32800000,0x00000000)}},
+        {VT_exponent,22,0x3a85ff,{DOUBLEWITHTWODWORDINTREE(0x32900000,0x00000000)}},
+        {VT_exponent,22,0x3a8600,{DOUBLEWITHTWODWORDINTREE(0x32a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8601,{DOUBLEWITHTWODWORDINTREE(0x32b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8602,{DOUBLEWITHTWODWORDINTREE(0x32c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8603,{DOUBLEWITHTWODWORDINTREE(0x32d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8604,{DOUBLEWITHTWODWORDINTREE(0x32e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8605,{DOUBLEWITHTWODWORDINTREE(0x32f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8606,{DOUBLEWITHTWODWORDINTREE(0x33000000,0x00000000)}},
+        {VT_exponent,22,0x3a8607,{DOUBLEWITHTWODWORDINTREE(0x33100000,0x00000000)}},
+        {VT_exponent,22,0x3a8608,{DOUBLEWITHTWODWORDINTREE(0x33200000,0x00000000)}},
+        {VT_exponent,22,0x3a8609,{DOUBLEWITHTWODWORDINTREE(0x33300000,0x00000000)}},
+        {VT_exponent,22,0x3a860a,{DOUBLEWITHTWODWORDINTREE(0x33400000,0x00000000)}},
+        {VT_exponent,22,0x3a860b,{DOUBLEWITHTWODWORDINTREE(0x33500000,0x00000000)}},
+        {VT_exponent,22,0x3a860c,{DOUBLEWITHTWODWORDINTREE(0x33600000,0x00000000)}},
+        {VT_exponent,22,0x3a860d,{DOUBLEWITHTWODWORDINTREE(0x33700000,0x00000000)}},
+        {VT_exponent,22,0x3a860e,{DOUBLEWITHTWODWORDINTREE(0x33800000,0x00000000)}},
+        {VT_exponent,22,0x3a860f,{DOUBLEWITHTWODWORDINTREE(0x33900000,0x00000000)}},
+        {VT_exponent,22,0x3a8610,{DOUBLEWITHTWODWORDINTREE(0x33a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8611,{DOUBLEWITHTWODWORDINTREE(0x33b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8612,{DOUBLEWITHTWODWORDINTREE(0x33c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8613,{DOUBLEWITHTWODWORDINTREE(0x33d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8614,{DOUBLEWITHTWODWORDINTREE(0x33e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8615,{DOUBLEWITHTWODWORDINTREE(0x33f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8616,{DOUBLEWITHTWODWORDINTREE(0x34000000,0x00000000)}},
+        {VT_exponent,22,0x3a8617,{DOUBLEWITHTWODWORDINTREE(0x34100000,0x00000000)}},
+        {VT_exponent,22,0x3a8618,{DOUBLEWITHTWODWORDINTREE(0x34200000,0x00000000)}},
+        {VT_exponent,22,0x3a8619,{DOUBLEWITHTWODWORDINTREE(0x34300000,0x00000000)}},
+        {VT_exponent,22,0x3a861a,{DOUBLEWITHTWODWORDINTREE(0x34400000,0x00000000)}},
+        {VT_exponent,22,0x3a861b,{DOUBLEWITHTWODWORDINTREE(0x34500000,0x00000000)}},
+        {VT_exponent,22,0x3a861c,{DOUBLEWITHTWODWORDINTREE(0x34600000,0x00000000)}},
+        {VT_exponent,22,0x3a861d,{DOUBLEWITHTWODWORDINTREE(0x34700000,0x00000000)}},
+        {VT_exponent,22,0x3a861e,{DOUBLEWITHTWODWORDINTREE(0x34800000,0x00000000)}},
+        {VT_exponent,22,0x3a861f,{DOUBLEWITHTWODWORDINTREE(0x34900000,0x00000000)}},
+        {VT_exponent,22,0x3a8620,{DOUBLEWITHTWODWORDINTREE(0x34a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8621,{DOUBLEWITHTWODWORDINTREE(0x34b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8622,{DOUBLEWITHTWODWORDINTREE(0x34c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8623,{DOUBLEWITHTWODWORDINTREE(0x34d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8624,{DOUBLEWITHTWODWORDINTREE(0x34e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8625,{DOUBLEWITHTWODWORDINTREE(0x34f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8626,{DOUBLEWITHTWODWORDINTREE(0x35000000,0x00000000)}},
+        {VT_exponent,22,0x3a8627,{DOUBLEWITHTWODWORDINTREE(0x35100000,0x00000000)}},
+        {VT_exponent,22,0x3a8628,{DOUBLEWITHTWODWORDINTREE(0x35200000,0x00000000)}},
+        {VT_exponent,22,0x3a8629,{DOUBLEWITHTWODWORDINTREE(0x35300000,0x00000000)}},
+        {VT_exponent,18,0xf787,{DOUBLEWITHTWODWORDINTREE(0x35400000,0x00000000)}},
+        {VT_exponent,18,0xd1d4,{DOUBLEWITHTWODWORDINTREE(0x35500000,0x00000000)}},
+        {VT_exponent,19,0x77f9f,{DOUBLEWITHTWODWORDINTREE(0x35600000,0x00000000)}},
+        {VT_exponent,18,0x3b8fb,{DOUBLEWITHTWODWORDINTREE(0x35700000,0x00000000)}},
+        {VT_exponent,19,0x1ef1a,{DOUBLEWITHTWODWORDINTREE(0x35800000,0x00000000)}},
+        {VT_exponent,21,0x1d4315,{DOUBLEWITHTWODWORDINTREE(0x35900000,0x00000000)}},
+        {VT_exponent,16,0x3de2,{DOUBLEWITHTWODWORDINTREE(0x35a00000,0x00000000)}},
+        {VT_exponent,22,0x3a862c,{DOUBLEWITHTWODWORDINTREE(0x35b00000,0x00000000)}},
+        {VT_exponent,22,0x3a862d,{DOUBLEWITHTWODWORDINTREE(0x35c00000,0x00000000)}},
+        {VT_exponent,22,0x3a862e,{DOUBLEWITHTWODWORDINTREE(0x35d00000,0x00000000)}},
+        {VT_exponent,22,0x3a862f,{DOUBLEWITHTWODWORDINTREE(0x35e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8630,{DOUBLEWITHTWODWORDINTREE(0x35f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8631,{DOUBLEWITHTWODWORDINTREE(0x36000000,0x00000000)}},
+        {VT_exponent,22,0x3a8632,{DOUBLEWITHTWODWORDINTREE(0x36100000,0x00000000)}},
+        {VT_exponent,22,0x3a8633,{DOUBLEWITHTWODWORDINTREE(0x36200000,0x00000000)}},
+        {VT_exponent,22,0x3a8634,{DOUBLEWITHTWODWORDINTREE(0x36300000,0x00000000)}},
+        {VT_exponent,22,0x3a8635,{DOUBLEWITHTWODWORDINTREE(0x36400000,0x00000000)}},
+        {VT_exponent,22,0x3a8636,{DOUBLEWITHTWODWORDINTREE(0x36500000,0x00000000)}},
+        {VT_exponent,22,0x3a8637,{DOUBLEWITHTWODWORDINTREE(0x36600000,0x00000000)}},
+        {VT_exponent,22,0x3a8638,{DOUBLEWITHTWODWORDINTREE(0x36700000,0x00000000)}},
+        {VT_exponent,21,0x1d431d,{DOUBLEWITHTWODWORDINTREE(0x36800000,0x00000000)}},
+        {VT_exponent,22,0x3a8639,{DOUBLEWITHTWODWORDINTREE(0x36900000,0x00000000)}},
+        {VT_exponent,22,0x3a863c,{DOUBLEWITHTWODWORDINTREE(0x36a00000,0x00000000)}},
+        {VT_exponent,16,0x3de0,{DOUBLEWITHTWODWORDINTREE(0x36b00000,0x00000000)}},
+        {VT_exponent,18,0x3a95e,{DOUBLEWITHTWODWORDINTREE(0x36c00000,0x00000000)}},
+        {VT_exponent,21,0x1d431f,{DOUBLEWITHTWODWORDINTREE(0x36d00000,0x00000000)}},
+        {VT_exponent,22,0x3a863d,{DOUBLEWITHTWODWORDINTREE(0x36e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8640,{DOUBLEWITHTWODWORDINTREE(0x36f00000,0x00000000)}},
+        {VT_exponent,20,0x34749,{DOUBLEWITHTWODWORDINTREE(0x37000000,0x00000000)}},
+        {VT_exponent,20,0x3474d,{DOUBLEWITHTWODWORDINTREE(0x37100000,0x00000000)}},
+        {VT_exponent,22,0x3a8641,{DOUBLEWITHTWODWORDINTREE(0x37200000,0x00000000)}},
+        {VT_exponent,22,0x3a8642,{DOUBLEWITHTWODWORDINTREE(0x37300000,0x00000000)}},
+        {VT_exponent,22,0x3a8643,{DOUBLEWITHTWODWORDINTREE(0x37400000,0x00000000)}},
+        {VT_exponent,22,0x3a8644,{DOUBLEWITHTWODWORDINTREE(0x37500000,0x00000000)}},
+        {VT_exponent,22,0x3a8645,{DOUBLEWITHTWODWORDINTREE(0x37600000,0x00000000)}},
+        {VT_exponent,22,0x3a8646,{DOUBLEWITHTWODWORDINTREE(0x37700000,0x00000000)}},
+        {VT_exponent,22,0x3a8647,{DOUBLEWITHTWODWORDINTREE(0x37800000,0x00000000)}},
+        {VT_exponent,22,0x3a8648,{DOUBLEWITHTWODWORDINTREE(0x37900000,0x00000000)}},
+        {VT_exponent,22,0x3a8649,{DOUBLEWITHTWODWORDINTREE(0x37a00000,0x00000000)}},
+        {VT_exponent,22,0x3a864a,{DOUBLEWITHTWODWORDINTREE(0x37b00000,0x00000000)}},
+        {VT_exponent,22,0x3a864b,{DOUBLEWITHTWODWORDINTREE(0x37c00000,0x00000000)}},
+        {VT_exponent,22,0x3a864c,{DOUBLEWITHTWODWORDINTREE(0x37d00000,0x00000000)}},
+        {VT_exponent,22,0x3a864d,{DOUBLEWITHTWODWORDINTREE(0x37e00000,0x00000000)}},
+        {VT_exponent,22,0x3a864e,{DOUBLEWITHTWODWORDINTREE(0x37f00000,0x00000000)}},
+        {VT_exponent,22,0x3a864f,{DOUBLEWITHTWODWORDINTREE(0x38000000,0x00000000)}},
+        {VT_exponent,22,0x3a8650,{DOUBLEWITHTWODWORDINTREE(0x38100000,0x00000000)}},
+        {VT_exponent,22,0x3a8651,{DOUBLEWITHTWODWORDINTREE(0x38200000,0x00000000)}},
+        {VT_exponent,22,0x3a8652,{DOUBLEWITHTWODWORDINTREE(0x38300000,0x00000000)}},
+        {VT_exponent,22,0x3a8653,{DOUBLEWITHTWODWORDINTREE(0x38400000,0x00000000)}},
+        {VT_exponent,22,0x3a8654,{DOUBLEWITHTWODWORDINTREE(0x38500000,0x00000000)}},
+        {VT_exponent,22,0x3a8655,{DOUBLEWITHTWODWORDINTREE(0x38600000,0x00000000)}},
+        {VT_exponent,22,0x3a8656,{DOUBLEWITHTWODWORDINTREE(0x38700000,0x00000000)}},
+        {VT_exponent,22,0x3a8657,{DOUBLEWITHTWODWORDINTREE(0x38800000,0x00000000)}},
+        {VT_exponent,22,0x3a8658,{DOUBLEWITHTWODWORDINTREE(0x38900000,0x00000000)}},
+        {VT_exponent,22,0x3a8659,{DOUBLEWITHTWODWORDINTREE(0x38a00000,0x00000000)}},
+        {VT_exponent,22,0x3a865a,{DOUBLEWITHTWODWORDINTREE(0x38b00000,0x00000000)}},
+        {VT_exponent,22,0x3a865b,{DOUBLEWITHTWODWORDINTREE(0x38c00000,0x00000000)}},
+        {VT_exponent,22,0x3a865c,{DOUBLEWITHTWODWORDINTREE(0x38d00000,0x00000000)}},
+        {VT_exponent,22,0x3a865d,{DOUBLEWITHTWODWORDINTREE(0x38e00000,0x00000000)}},
+        {VT_exponent,21,0x1d432f,{DOUBLEWITHTWODWORDINTREE(0x38f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8660,{DOUBLEWITHTWODWORDINTREE(0x39000000,0x00000000)}},
+        {VT_exponent,22,0x3a8661,{DOUBLEWITHTWODWORDINTREE(0x39100000,0x00000000)}},
+        {VT_exponent,22,0x3a8662,{DOUBLEWITHTWODWORDINTREE(0x39200000,0x00000000)}},
+        {VT_exponent,21,0x1d4332,{DOUBLEWITHTWODWORDINTREE(0x39300000,0x00000000)}},
+        {VT_exponent,18,0xd1d5,{DOUBLEWITHTWODWORDINTREE(0x39400000,0x00000000)}},
+        {VT_exponent,18,0x3bfda,{DOUBLEWITHTWODWORDINTREE(0x39500000,0x00000000)}},
+        {VT_exponent,15,0x7528,{DOUBLEWITHTWODWORDINTREE(0x39600000,0x00000000)}},
+        {VT_exponent,15,0x7529,{DOUBLEWITHTWODWORDINTREE(0x39700000,0x00000000)}},
+        {VT_exponent,18,0x3a95f,{DOUBLEWITHTWODWORDINTREE(0x39800000,0x00000000)}},
+        {VT_exponent,17,0x1d434,{DOUBLEWITHTWODWORDINTREE(0x39900000,0x00000000)}},
+        {VT_exponent,19,0x750cd,{DOUBLEWITHTWODWORDINTREE(0x39a00000,0x00000000)}},
+        {VT_exponent,18,0x3a867,{DOUBLEWITHTWODWORDINTREE(0x39b00000,0x00000000)}},
+        {VT_exponent,19,0x771fd,{DOUBLEWITHTWODWORDINTREE(0x39c00000,0x00000000)}},
+        {VT_exponent,15,0x7764,{DOUBLEWITHTWODWORDINTREE(0x39d00000,0x00000000)}},
+        {VT_exponent,20,0xee3f9,{DOUBLEWITHTWODWORDINTREE(0x39e00000,0x00000000)}},
+        {VT_exponent,18,0x3bfdb,{DOUBLEWITHTWODWORDINTREE(0x39f00000,0x00000000)}},
+        {VT_exponent,16,0xeff7,{DOUBLEWITHTWODWORDINTREE(0x3a000000,0x00000000)}},
+        {VT_exponent,18,0xd1d6,{DOUBLEWITHTWODWORDINTREE(0x3a100000,0x00000000)}},
+        {VT_exponent,22,0x3a8663,{DOUBLEWITHTWODWORDINTREE(0x3a200000,0x00000000)}},
+        {VT_exponent,22,0x3a8666,{DOUBLEWITHTWODWORDINTREE(0x3a300000,0x00000000)}},
+        {VT_exponent,18,0x3b8fa,{DOUBLEWITHTWODWORDINTREE(0x3a400000,0x00000000)}},
+        {VT_exponent,17,0x1d435,{DOUBLEWITHTWODWORDINTREE(0x3a500000,0x00000000)}},
+        {VT_exponent,17,0x1dfe4,{DOUBLEWITHTWODWORDINTREE(0x3a600000,0x00000000)}},
+        {VT_exponent,19,0x750d8,{DOUBLEWITHTWODWORDINTREE(0x3a700000,0x00000000)}},
+        {VT_exponent,18,0x3a95b,{DOUBLEWITHTWODWORDINTREE(0x3a800000,0x00000000)}},
+        {VT_exponent,19,0x77f9e,{DOUBLEWITHTWODWORDINTREE(0x3a900000,0x00000000)}},
+        {VT_exponent,19,0x750d9,{DOUBLEWITHTWODWORDINTREE(0x3aa00000,0x00000000)}},
+        {VT_exponent,18,0xd1d7,{DOUBLEWITHTWODWORDINTREE(0x3ab00000,0x00000000)}},
+        {VT_exponent,18,0x3b8ff,{DOUBLEWITHTWODWORDINTREE(0x3ac00000,0x00000000)}},
+        {VT_exponent,17,0x1dc7c,{DOUBLEWITHTWODWORDINTREE(0x3ad00000,0x00000000)}},
+        {VT_exponent,19,0x750da,{DOUBLEWITHTWODWORDINTREE(0x3ae00000,0x00000000)}},
+        {VT_exponent,17,0x7bc2,{DOUBLEWITHTWODWORDINTREE(0x3af00000,0x00000000)}},
+        {VT_exponent,18,0x3bfca,{DOUBLEWITHTWODWORDINTREE(0x3b000000,0x00000000)}},
+        {VT_exponent,19,0x1a3a5,{DOUBLEWITHTWODWORDINTREE(0x3b100000,0x00000000)}},
+        {VT_exponent,17,0x1d4ac,{DOUBLEWITHTWODWORDINTREE(0x3b200000,0x00000000)}},
+        {VT_exponent,18,0x3a86e,{DOUBLEWITHTWODWORDINTREE(0x3b300000,0x00000000)}},
+        {VT_exponent,17,0x1d438,{DOUBLEWITHTWODWORDINTREE(0x3b400000,0x00000000)}},
+        {VT_exponent,18,0x3bfcb,{DOUBLEWITHTWODWORDINTREE(0x3b500000,0x00000000)}},
+        {VT_exponent,19,0x1a3a7,{DOUBLEWITHTWODWORDINTREE(0x3b600000,0x00000000)}},
+        {VT_exponent,17,0x1d4ae,{DOUBLEWITHTWODWORDINTREE(0x3b700000,0x00000000)}},
+        {VT_exponent,18,0x3bfce,{DOUBLEWITHTWODWORDINTREE(0x3b800000,0x00000000)}},
+        {VT_exponent,18,0xf78c,{DOUBLEWITHTWODWORDINTREE(0x3b900000,0x00000000)}},
+        {VT_exponent,17,0x1dfec,{DOUBLEWITHTWODWORDINTREE(0x3ba00000,0x00000000)}},
+        {VT_exponent,17,0x1d439,{DOUBLEWITHTWODWORDINTREE(0x3bb00000,0x00000000)}},
+        {VT_exponent,17,0x68e8,{DOUBLEWITHTWODWORDINTREE(0x3bc00000,0x00000000)}},
+        {VT_exponent,18,0xf786,{DOUBLEWITHTWODWORDINTREE(0x3bd00000,0x00000000)}},
+        {VT_exponent,15,0x771e,{DOUBLEWITHTWODWORDINTREE(0x3be00000,0x00000000)}},
+        {VT_exponent,17,0x1dfe6,{DOUBLEWITHTWODWORDINTREE(0x3bf00000,0x00000000)}},
+        {VT_exponent,15,0x77f8,{DOUBLEWITHTWODWORDINTREE(0x3c000000,0x00000000)}},
+        {VT_exponent,14,0x3bb3,{DOUBLEWITHTWODWORDINTREE(0x3c100000,0x00000000)}},
+        {VT_exponent,14,0x3b8e,{DOUBLEWITHTWODWORDINTREE(0x3c200000,0x00000000)}},
+        {VT_exponent,14,0x3a82,{DOUBLEWITHTWODWORDINTREE(0x3c300000,0x00000000)}},
+        {VT_exponent,14,0x3b96,{DOUBLEWITHTWODWORDINTREE(0x3c400000,0x00000000)}},
+        {VT_exponent,13,0x68f,{DOUBLEWITHTWODWORDINTREE(0x3c500000,0x00000000)}},
+        {VT_exponent,12,0x3d4,{DOUBLEWITHTWODWORDINTREE(0x3c600000,0x00000000)}},
+        {VT_exponent,13,0x1dca,{DOUBLEWITHTWODWORDINTREE(0x3c700000,0x00000000)}},
+        {VT_exponent,12,0x346,{DOUBLEWITHTWODWORDINTREE(0x3c800000,0x00000000)}},
+        {VT_exponent,12,0xee7,{DOUBLEWITHTWODWORDINTREE(0x3c900000,0x00000000)}},
+        {VT_exponent,12,0xeea,{DOUBLEWITHTWODWORDINTREE(0x3ca00000,0x00000000)}},
+        {VT_exponent,11,0x1ed,{DOUBLEWITHTWODWORDINTREE(0x3cb00000,0x00000000)}},
+        {VT_exponent,12,0x3df,{DOUBLEWITHTWODWORDINTREE(0x3cc00000,0x00000000)}},
+        {VT_exponent,11,0x1a2,{DOUBLEWITHTWODWORDINTREE(0x3cd00000,0x00000000)}},
+        {VT_exponent,11,0x56f,{DOUBLEWITHTWODWORDINTREE(0x3ce00000,0x00000000)}},
+        {VT_exponent,11,0xb9,{DOUBLEWITHTWODWORDINTREE(0x3cf00000,0x00000000)}},
+        {VT_exponent,13,0x7b2,{DOUBLEWITHTWODWORDINTREE(0x3d000000,0x00000000)}},
+        {VT_exponent,13,0x1dd8,{DOUBLEWITHTWODWORDINTREE(0x3d100000,0x00000000)}},
+        {VT_exponent,13,0x15ba,{DOUBLEWITHTWODWORDINTREE(0x3d200000,0x00000000)}},
+        {VT_exponent,12,0xee6,{DOUBLEWITHTWODWORDINTREE(0x3d300000,0x00000000)}},
+        {VT_exponent,13,0x15b8,{DOUBLEWITHTWODWORDINTREE(0x3d400000,0x00000000)}},
+        {VT_exponent,14,0xf79,{DOUBLEWITHTWODWORDINTREE(0x3d500000,0x00000000)}},
+        {VT_exponent,14,0x3a81,{DOUBLEWITHTWODWORDINTREE(0x3d600000,0x00000000)}},
+        {VT_exponent,14,0xd1c,{DOUBLEWITHTWODWORDINTREE(0x3d700000,0x00000000)}},
+        {VT_exponent,15,0x7765,{DOUBLEWITHTWODWORDINTREE(0x3d800000,0x00000000)}},
+        {VT_exponent,14,0xf54,{DOUBLEWITHTWODWORDINTREE(0x3d900000,0x00000000)}},
+        {VT_exponent,13,0x15b9,{DOUBLEWITHTWODWORDINTREE(0x3da00000,0x00000000)}},
+        {VT_exponent,13,0x7ab,{DOUBLEWITHTWODWORDINTREE(0x3db00000,0x00000000)}},
+        {VT_exponent,15,0x7500,{DOUBLEWITHTWODWORDINTREE(0x3dc00000,0x00000000)}},
+        {VT_exponent,15,0x1eaa,{DOUBLEWITHTWODWORDINTREE(0x3dd00000,0x00000000)}},
+        {VT_exponent,15,0x7501,{DOUBLEWITHTWODWORDINTREE(0x3de00000,0x00000000)}},
+        {VT_exponent,15,0x1eab,{DOUBLEWITHTWODWORDINTREE(0x3df00000,0x00000000)}},
+        {VT_exponent,14,0x3b97,{DOUBLEWITHTWODWORDINTREE(0x3e000000,0x00000000)}},
+        {VT_exponent,15,0x752a,{DOUBLEWITHTWODWORDINTREE(0x3e100000,0x00000000)}},
+        {VT_exponent,15,0x77fa,{DOUBLEWITHTWODWORDINTREE(0x3e200000,0x00000000)}},
+        {VT_double,10,0xf4,{DOUBLEWITHTWODWORDINTREE(0x3e35798e,0xe2308c3a)}},
+        {VT_exponent,14,0x3a93,{DOUBLEWITHTWODWORDINTREE(0x3e300000,0x00000000)}},
+        {VT_double,11,0x77c,{DOUBLEWITHTWODWORDINTREE(0x3e45798e,0xe2308c3a)}},
+        {VT_exponent,13,0x1dc6,{DOUBLEWITHTWODWORDINTREE(0x3e400000,0x00000000)}},
+        {VT_exponent,13,0x7bd,{DOUBLEWITHTWODWORDINTREE(0x3e500000,0x00000000)}},
+        {VT_exponent,13,0x1dff,{DOUBLEWITHTWODWORDINTREE(0x3e600000,0x00000000)}},
+        {VT_exponent,12,0xefe,{DOUBLEWITHTWODWORDINTREE(0x3e700000,0x00000000)}},
+        {VT_double,8,0xaf,{DOUBLEWITHTWODWORDINTREE(0x3e8ad7f2,0x9abcaf4a)}},
+        {VT_exponent,12,0xeed,{DOUBLEWITHTWODWORDINTREE(0x3e800000,0x00000000)}},
+        {VT_exponent,11,0xb8,{DOUBLEWITHTWODWORDINTREE(0x3e900000,0x00000000)}},
+        {VT_exponent,12,0x3d8,{DOUBLEWITHTWODWORDINTREE(0x3ea00000,0x00000000)}},
+        {VT_exponent,11,0x1eb,{DOUBLEWITHTWODWORDINTREE(0x3eb00000,0x00000000)}},
+        {VT_double,9,0x1d2,{DOUBLEWITHTWODWORDINTREE(0x3ec0c6f7,0xa0b5ed8e)}},
+        {VT_exponent,13,0x1d4b,{DOUBLEWITHTWODWORDINTREE(0x3ec00000,0x00000000)}},
+        {VT_exponent,13,0x7b3,{DOUBLEWITHTWODWORDINTREE(0x3ed00000,0x00000000)}},
+        {VT_exponent,10,0x5d,{DOUBLEWITHTWODWORDINTREE(0x3ee00000,0x00000000)}},
+        {VT_exponent,12,0xeeb,{DOUBLEWITHTWODWORDINTREE(0x3ef00000,0x00000000)}},
+        {VT_exponent,11,0x1ee,{DOUBLEWITHTWODWORDINTREE(0x3f000000,0x00000000)}},
+        {VT_exponent,10,0x5f,{DOUBLEWITHTWODWORDINTREE(0x3f100000,0x00000000)}},
+        {VT_exponent,10,0x2b6,{DOUBLEWITHTWODWORDINTREE(0x3f200000,0x00000000)}},
+        {VT_exponent,9,0x1de,{DOUBLEWITHTWODWORDINTREE(0x3f300000,0x00000000)}},
+        {VT_double,10,0xd0,{DOUBLEWITHTWODWORDINTREE(0x3f454c98,0x5f06f694)}},
+        {VT_double,6,0x9,{DOUBLEWITHTWODWORDINTREE(0x3f4a36e2,0xeb1c432d)}},
+        {VT_exponent,8,0xe8,{DOUBLEWITHTWODWORDINTREE(0x3f400000,0x00000000)}},
+        {VT_double,4,0xf,{DOUBLEWITHTWODWORDINTREE(0x3f50624d,0xd2f1a9fc)}},
+        {VT_exponent,8,0xae,{DOUBLEWITHTWODWORDINTREE(0x3f500000,0x00000000)}},
+        {VT_double,5,0x16,{DOUBLEWITHTWODWORDINTREE(0x3f60624d,0xd2f1a9fc)}},
+        {VT_exponent,7,0x1b,{DOUBLEWITHTWODWORDINTREE(0x3f600000,0x00000000)}},
+        {VT_exponent,7,0x76,{DOUBLEWITHTWODWORDINTREE(0x3f700000,0x00000000)}},
+        {VT_exponent,7,0xa,{DOUBLEWITHTWODWORDINTREE(0x3f800000,0x00000000)}},
+        {VT_exponent,6,0x8,{DOUBLEWITHTWODWORDINTREE(0x3f900000,0x00000000)}},
+        {VT_exponent,6,0xe,{DOUBLEWITHTWODWORDINTREE(0x3fa00000,0x00000000)}},
+        {VT_double,11,0x751,{DOUBLEWITHTWODWORDINTREE(0x3fbe69ad,0x42c3c9ee)}},
+        {VT_exponent,6,0x4,{DOUBLEWITHTWODWORDINTREE(0x3fb00000,0x00000000)}},
+        {VT_exponent,6,0xc,{DOUBLEWITHTWODWORDINTREE(0x3fc00000,0x00000000)}},
+        {VT_exponent,5,0x3,{DOUBLEWITHTWODWORDINTREE(0x3fd00000,0x00000000)}},
+        {VT_double,11,0x777,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+        {VT_double,9,0x1d6,{DOUBLEWITHTWODWORDINTREE(0x3fefffff,0xf8000002)}},
+        {VT_exponent,4,0x8,{DOUBLEWITHTWODWORDINTREE(0x3fe00000,0x00000000)}},
+        {VT_double,4,0x0,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+        {VT_exponent,5,0x13,{DOUBLEWITHTWODWORDINTREE(0x3ff00000,0x00000000)}},
+        {VT_exponent,5,0x1b,{DOUBLEWITHTWODWORDINTREE(0x40000000,0x00000000)}},
+        {VT_double,9,0x15a,{DOUBLEWITHTWODWORDINTREE(0x401921fb,0x54442d18)}},
+        {VT_exponent,5,0x17,{DOUBLEWITHTWODWORDINTREE(0x40100000,0x00000000)}},
+        {VT_exponent,5,0x12,{DOUBLEWITHTWODWORDINTREE(0x40200000,0x00000000)}},
+        {VT_double,11,0x774,{DOUBLEWITHTWODWORDINTREE(0x4035ee14,0x80000000)}},
+        {VT_exponent,5,0x19,{DOUBLEWITHTWODWORDINTREE(0x40300000,0x00000000)}},
+        {VT_double,9,0x1d3,{DOUBLEWITHTWODWORDINTREE(0x404ca5dc,0x1a63c1f8)}},
+        {VT_exponent,5,0x1a,{DOUBLEWITHTWODWORDINTREE(0x40400000,0x00000000)}},
+        {VT_double,11,0x77e,{DOUBLEWITHTWODWORDINTREE(0x405bb32f,0xe0000000)}},
+        {VT_double,10,0x5e,{DOUBLEWITHTWODWORDINTREE(0x405c332f,0xe0000000)}},
+        {VT_exponent,5,0x18,{DOUBLEWITHTWODWORDINTREE(0x40500000,0x00000000)}},
+        {VT_double,9,0x1d7,{DOUBLEWITHTWODWORDINTREE(0x40668000,0x00000000)}},
+        {VT_exponent,5,0x1c,{DOUBLEWITHTWODWORDINTREE(0x40600000,0x00000000)}},
+        {VT_double,9,0x1d5,{DOUBLEWITHTWODWORDINTREE(0x40768000,0x00000000)}},
+        {VT_exponent,5,0x14,{DOUBLEWITHTWODWORDINTREE(0x40700000,0x00000000)}},
+        {VT_double,11,0x77d,{DOUBLEWITHTWODWORDINTREE(0x408f4000,0x00000000)}},
+        {VT_exponent,5,0x5,{DOUBLEWITHTWODWORDINTREE(0x40800000,0x00000000)}},
+        {VT_double,10,0xd2,{DOUBLEWITHTWODWORDINTREE(0x409233ff,0xffffffff)}},
+        {VT_double,8,0x3c,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000000)}},
+        {VT_double,11,0x753,{DOUBLEWITHTWODWORDINTREE(0x40923400,0x00000001)}},
+        {VT_double,10,0xd3,{DOUBLEWITHTWODWORDINTREE(0x4092abff,0xffffffff)}},
+        {VT_double,8,0x35,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000000)}},
+        {VT_double,11,0x770,{DOUBLEWITHTWODWORDINTREE(0x4092ac00,0x00000001)}},
+        {VT_exponent,8,0x16,{DOUBLEWITHTWODWORDINTREE(0x40900000,0x00000000)}},
+        {VT_exponent,12,0xee2,{DOUBLEWITHTWODWORDINTREE(0x40a00000,0x00000000)}},
+        {VT_exponent,12,0xee4,{DOUBLEWITHTWODWORDINTREE(0x40b00000,0x00000000)}},
+        {VT_double,7,0x1f,{DOUBLEWITHTWODWORDINTREE(0x40c81c80,0x00000000)}},
+        {VT_exponent,8,0xac,{DOUBLEWITHTWODWORDINTREE(0x40c00000,0x00000000)}},
+        {VT_exponent,13,0x15bb,{DOUBLEWITHTWODWORDINTREE(0x40d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8667,{DOUBLEWITHTWODWORDINTREE(0x40e00000,0x00000000)}},
+        {VT_exponent,22,0x3a86d8,{DOUBLEWITHTWODWORDINTREE(0x40f00000,0x00000000)}},
+        {VT_exponent,22,0x3a86d9,{DOUBLEWITHTWODWORDINTREE(0x41000000,0x00000000)}},
+        {VT_exponent,22,0x3a86da,{DOUBLEWITHTWODWORDINTREE(0x41100000,0x00000000)}},
+        {VT_exponent,17,0x1dc7e,{DOUBLEWITHTWODWORDINTREE(0x41200000,0x00000000)}},
+        {VT_exponent,22,0x3a86db,{DOUBLEWITHTWODWORDINTREE(0x41300000,0x00000000)}},
+        {VT_exponent,22,0x3a86dc,{DOUBLEWITHTWODWORDINTREE(0x41400000,0x00000000)}},
+        {VT_exponent,22,0x3a86dd,{DOUBLEWITHTWODWORDINTREE(0x41500000,0x00000000)}},
+        {VT_exponent,22,0x3a86de,{DOUBLEWITHTWODWORDINTREE(0x41600000,0x00000000)}},
+        {VT_exponent,22,0x3a86df,{DOUBLEWITHTWODWORDINTREE(0x41700000,0x00000000)}},
+        {VT_exponent,22,0x3a86f0,{DOUBLEWITHTWODWORDINTREE(0x41800000,0x00000000)}},
+        {VT_exponent,22,0x3a86f1,{DOUBLEWITHTWODWORDINTREE(0x41900000,0x00000000)}},
+        {VT_exponent,22,0x3a86f2,{DOUBLEWITHTWODWORDINTREE(0x41a00000,0x00000000)}},
+        {VT_exponent,22,0x3a86f3,{DOUBLEWITHTWODWORDINTREE(0x41b00000,0x00000000)}},
+        {VT_double,6,0x2a,{DOUBLEWITHTWODWORDINTREE(0x41cdcd64,0xff800000)}},
+        {VT_exponent,22,0x3a86f4,{DOUBLEWITHTWODWORDINTREE(0x41c00000,0x00000000)}},
+        {VT_exponent,22,0x3a86f5,{DOUBLEWITHTWODWORDINTREE(0x41d00000,0x00000000)}},
+        {VT_exponent,22,0x3a86f6,{DOUBLEWITHTWODWORDINTREE(0x41e00000,0x00000000)}},
+        {VT_exponent,22,0x3a86f7,{DOUBLEWITHTWODWORDINTREE(0x41f00000,0x00000000)}},
+        {VT_exponent,22,0x3a86f8,{DOUBLEWITHTWODWORDINTREE(0x42000000,0x00000000)}},
+        {VT_exponent,22,0x3a86f9,{DOUBLEWITHTWODWORDINTREE(0x42100000,0x00000000)}},
+        {VT_exponent,22,0x3a86fa,{DOUBLEWITHTWODWORDINTREE(0x42200000,0x00000000)}},
+        {VT_exponent,22,0x3a86fb,{DOUBLEWITHTWODWORDINTREE(0x42300000,0x00000000)}},
+        {VT_exponent,22,0x3a86fc,{DOUBLEWITHTWODWORDINTREE(0x42400000,0x00000000)}},
+        {VT_exponent,22,0x3a86fd,{DOUBLEWITHTWODWORDINTREE(0x42500000,0x00000000)}},
+        {VT_exponent,22,0x3a86fe,{DOUBLEWITHTWODWORDINTREE(0x42600000,0x00000000)}},
+        {VT_exponent,22,0x3a86ff,{DOUBLEWITHTWODWORDINTREE(0x42700000,0x00000000)}},
+        {VT_exponent,22,0x3a8740,{DOUBLEWITHTWODWORDINTREE(0x42800000,0x00000000)}},
+        {VT_exponent,22,0x3a8741,{DOUBLEWITHTWODWORDINTREE(0x42900000,0x00000000)}},
+        {VT_exponent,22,0x3a8742,{DOUBLEWITHTWODWORDINTREE(0x42a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8743,{DOUBLEWITHTWODWORDINTREE(0x42b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8744,{DOUBLEWITHTWODWORDINTREE(0x42c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8745,{DOUBLEWITHTWODWORDINTREE(0x42d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8746,{DOUBLEWITHTWODWORDINTREE(0x42e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8747,{DOUBLEWITHTWODWORDINTREE(0x42f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8748,{DOUBLEWITHTWODWORDINTREE(0x43000000,0x00000000)}},
+        {VT_exponent,22,0x3a8749,{DOUBLEWITHTWODWORDINTREE(0x43100000,0x00000000)}},
+        {VT_exponent,22,0x3a874a,{DOUBLEWITHTWODWORDINTREE(0x43200000,0x00000000)}},
+        {VT_exponent,22,0x3a874b,{DOUBLEWITHTWODWORDINTREE(0x43300000,0x00000000)}},
+        {VT_exponent,22,0x3a874c,{DOUBLEWITHTWODWORDINTREE(0x43400000,0x00000000)}},
+        {VT_exponent,22,0x3a874d,{DOUBLEWITHTWODWORDINTREE(0x43500000,0x00000000)}},
+        {VT_exponent,22,0x3a874e,{DOUBLEWITHTWODWORDINTREE(0x43600000,0x00000000)}},
+        {VT_exponent,22,0x3a874f,{DOUBLEWITHTWODWORDINTREE(0x43700000,0x00000000)}},
+        {VT_exponent,22,0x3a8750,{DOUBLEWITHTWODWORDINTREE(0x43800000,0x00000000)}},
+        {VT_exponent,22,0x3a8751,{DOUBLEWITHTWODWORDINTREE(0x43900000,0x00000000)}},
+        {VT_exponent,22,0x3a8752,{DOUBLEWITHTWODWORDINTREE(0x43a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8753,{DOUBLEWITHTWODWORDINTREE(0x43b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8754,{DOUBLEWITHTWODWORDINTREE(0x43c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8755,{DOUBLEWITHTWODWORDINTREE(0x43d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8756,{DOUBLEWITHTWODWORDINTREE(0x43e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8757,{DOUBLEWITHTWODWORDINTREE(0x43f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8758,{DOUBLEWITHTWODWORDINTREE(0x44000000,0x00000000)}},
+        {VT_exponent,15,0x1a3b,{DOUBLEWITHTWODWORDINTREE(0x44100000,0x00000000)}},
+        {VT_exponent,22,0x3a8759,{DOUBLEWITHTWODWORDINTREE(0x44200000,0x00000000)}},
+        {VT_exponent,22,0x3a875a,{DOUBLEWITHTWODWORDINTREE(0x44300000,0x00000000)}},
+        {VT_exponent,22,0x3a875b,{DOUBLEWITHTWODWORDINTREE(0x44400000,0x00000000)}},
+        {VT_exponent,22,0x3a875c,{DOUBLEWITHTWODWORDINTREE(0x44500000,0x00000000)}},
+        {VT_exponent,22,0x3a875d,{DOUBLEWITHTWODWORDINTREE(0x44600000,0x00000000)}},
+        {VT_exponent,22,0x3a875e,{DOUBLEWITHTWODWORDINTREE(0x44700000,0x00000000)}},
+        {VT_exponent,22,0x3a875f,{DOUBLEWITHTWODWORDINTREE(0x44800000,0x00000000)}},
+        {VT_exponent,22,0x3a8760,{DOUBLEWITHTWODWORDINTREE(0x44900000,0x00000000)}},
+        {VT_exponent,22,0x3a8761,{DOUBLEWITHTWODWORDINTREE(0x44a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8762,{DOUBLEWITHTWODWORDINTREE(0x44b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8763,{DOUBLEWITHTWODWORDINTREE(0x44c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8764,{DOUBLEWITHTWODWORDINTREE(0x44d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8765,{DOUBLEWITHTWODWORDINTREE(0x44e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8766,{DOUBLEWITHTWODWORDINTREE(0x44f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8767,{DOUBLEWITHTWODWORDINTREE(0x45000000,0x00000000)}},
+        {VT_exponent,22,0x3a8768,{DOUBLEWITHTWODWORDINTREE(0x45100000,0x00000000)}},
+        {VT_exponent,22,0x3a8769,{DOUBLEWITHTWODWORDINTREE(0x45200000,0x00000000)}},
+        {VT_exponent,22,0x3a876a,{DOUBLEWITHTWODWORDINTREE(0x45300000,0x00000000)}},
+        {VT_exponent,22,0x3a876b,{DOUBLEWITHTWODWORDINTREE(0x45400000,0x00000000)}},
+        {VT_exponent,22,0x3a876c,{DOUBLEWITHTWODWORDINTREE(0x45500000,0x00000000)}},
+        {VT_exponent,22,0x3a876d,{DOUBLEWITHTWODWORDINTREE(0x45600000,0x00000000)}},
+        {VT_exponent,22,0x3a876e,{DOUBLEWITHTWODWORDINTREE(0x45700000,0x00000000)}},
+        {VT_exponent,22,0x3a876f,{DOUBLEWITHTWODWORDINTREE(0x45800000,0x00000000)}},
+        {VT_exponent,22,0x3a8770,{DOUBLEWITHTWODWORDINTREE(0x45900000,0x00000000)}},
+        {VT_exponent,22,0x3a8771,{DOUBLEWITHTWODWORDINTREE(0x45a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8772,{DOUBLEWITHTWODWORDINTREE(0x45b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8773,{DOUBLEWITHTWODWORDINTREE(0x45c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8774,{DOUBLEWITHTWODWORDINTREE(0x45d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8775,{DOUBLEWITHTWODWORDINTREE(0x45e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8776,{DOUBLEWITHTWODWORDINTREE(0x45f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8777,{DOUBLEWITHTWODWORDINTREE(0x46000000,0x00000000)}},
+        {VT_exponent,22,0x3a8778,{DOUBLEWITHTWODWORDINTREE(0x46100000,0x00000000)}},
+        {VT_exponent,22,0x3a8779,{DOUBLEWITHTWODWORDINTREE(0x46200000,0x00000000)}},
+        {VT_exponent,22,0x3a877a,{DOUBLEWITHTWODWORDINTREE(0x46300000,0x00000000)}},
+        {VT_exponent,22,0x3a877b,{DOUBLEWITHTWODWORDINTREE(0x46400000,0x00000000)}},
+        {VT_exponent,22,0x3a877c,{DOUBLEWITHTWODWORDINTREE(0x46500000,0x00000000)}},
+        {VT_exponent,22,0x3a877d,{DOUBLEWITHTWODWORDINTREE(0x46600000,0x00000000)}},
+        {VT_exponent,22,0x3a877e,{DOUBLEWITHTWODWORDINTREE(0x46700000,0x00000000)}},
+        {VT_exponent,22,0x3a877f,{DOUBLEWITHTWODWORDINTREE(0x46800000,0x00000000)}},
+        {VT_exponent,22,0x3a8780,{DOUBLEWITHTWODWORDINTREE(0x46900000,0x00000000)}},
+        {VT_exponent,22,0x3a8781,{DOUBLEWITHTWODWORDINTREE(0x46a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8782,{DOUBLEWITHTWODWORDINTREE(0x46b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8783,{DOUBLEWITHTWODWORDINTREE(0x46c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8784,{DOUBLEWITHTWODWORDINTREE(0x46d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8785,{DOUBLEWITHTWODWORDINTREE(0x46e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8786,{DOUBLEWITHTWODWORDINTREE(0x46f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8787,{DOUBLEWITHTWODWORDINTREE(0x47000000,0x00000000)}},
+        {VT_exponent,22,0x3a8788,{DOUBLEWITHTWODWORDINTREE(0x47100000,0x00000000)}},
+        {VT_exponent,22,0x3a8789,{DOUBLEWITHTWODWORDINTREE(0x47200000,0x00000000)}},
+        {VT_exponent,22,0x3a878a,{DOUBLEWITHTWODWORDINTREE(0x47300000,0x00000000)}},
+        {VT_exponent,22,0x3a878b,{DOUBLEWITHTWODWORDINTREE(0x47400000,0x00000000)}},
+        {VT_exponent,22,0x3a878c,{DOUBLEWITHTWODWORDINTREE(0x47500000,0x00000000)}},
+        {VT_exponent,22,0x3a878d,{DOUBLEWITHTWODWORDINTREE(0x47600000,0x00000000)}},
+        {VT_exponent,22,0x3a878e,{DOUBLEWITHTWODWORDINTREE(0x47700000,0x00000000)}},
+        {VT_exponent,22,0x3a878f,{DOUBLEWITHTWODWORDINTREE(0x47800000,0x00000000)}},
+        {VT_exponent,22,0x3a8790,{DOUBLEWITHTWODWORDINTREE(0x47900000,0x00000000)}},
+        {VT_exponent,22,0x3a8791,{DOUBLEWITHTWODWORDINTREE(0x47a00000,0x00000000)}},
+        {VT_exponent,22,0x3a8792,{DOUBLEWITHTWODWORDINTREE(0x47b00000,0x00000000)}},
+        {VT_exponent,22,0x3a8793,{DOUBLEWITHTWODWORDINTREE(0x47c00000,0x00000000)}},
+        {VT_exponent,22,0x3a8794,{DOUBLEWITHTWODWORDINTREE(0x47d00000,0x00000000)}},
+        {VT_exponent,22,0x3a8795,{DOUBLEWITHTWODWORDINTREE(0x47e00000,0x00000000)}},
+        {VT_exponent,22,0x3a8796,{DOUBLEWITHTWODWORDINTREE(0x47f00000,0x00000000)}},
+        {VT_exponent,22,0x3a8797,{DOUBLEWITHTWODWORDINTREE(0x48000000,0x00000000)}},
+        {VT_exponent,22,0x3a8798,{DOUBLEWITHTWODWORDINTREE(0x48100000,0x00000000)}},
+        {VT_exponent,22,0x3a8799,{DOUBLEWITHTWODWORDINTREE(0x48200000,0x00000000)}},
+        {VT_exponent,22,0x3a879a,{DOUBLEWITHTWODWORDINTREE(0x48300000,0x00000000)}},
+        {VT_exponent,22,0x3a879b,{DOUBLEWITHTWODWORDINTREE(0x48400000,0x00000000)}},
+        {VT_exponent,22,0x3a879c,{DOUBLEWITHTWODWORDINTREE(0x48500000,0x00000000)}},
+        {VT_exponent,22,0x3a879d,{DOUBLEWITHTWODWORDINTREE(0x48600000,0x00000000)}},
+        {VT_exponent,22,0x3a879e,{DOUBLEWITHTWODWORDINTREE(0x48700000,0x00000000)}},
+        {VT_exponent,22,0x3a879f,{DOUBLEWITHTWODWORDINTREE(0x48800000,0x00000000)}},
+        {VT_exponent,22,0x3a87a0,{DOUBLEWITHTWODWORDINTREE(0x48900000,0x00000000)}},
+        {VT_exponent,22,0x3a87a1,{DOUBLEWITHTWODWORDINTREE(0x48a00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a2,{DOUBLEWITHTWODWORDINTREE(0x48b00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a3,{DOUBLEWITHTWODWORDINTREE(0x48c00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a4,{DOUBLEWITHTWODWORDINTREE(0x48d00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a5,{DOUBLEWITHTWODWORDINTREE(0x48e00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a6,{DOUBLEWITHTWODWORDINTREE(0x48f00000,0x00000000)}},
+        {VT_exponent,22,0x3a87a7,{DOUBLEWITHTWODWORDINTREE(0x49000000,0x00000000)}},
+        {VT_exponent,22,0x3a87a8,{DOUBLEWITHTWODWORDINTREE(0x49100000,0x00000000)}},
+        {VT_exponent,22,0x3a87a9,{DOUBLEWITHTWODWORDINTREE(0x49200000,0x00000000)}},
+        {VT_exponent,22,0x3a87aa,{DOUBLEWITHTWODWORDINTREE(0x49300000,0x00000000)}},
+        {VT_exponent,22,0x3a87ab,{DOUBLEWITHTWODWORDINTREE(0x49400000,0x00000000)}},
+        {VT_exponent,22,0x3a87ac,{DOUBLEWITHTWODWORDINTREE(0x49500000,0x00000000)}},
+        {VT_exponent,22,0x3a87ad,{DOUBLEWITHTWODWORDINTREE(0x49600000,0x00000000)}},
+        {VT_exponent,22,0x3a87ae,{DOUBLEWITHTWODWORDINTREE(0x49700000,0x00000000)}},
+        {VT_exponent,22,0x3a87af,{DOUBLEWITHTWODWORDINTREE(0x49800000,0x00000000)}},
+        {VT_exponent,22,0x3a87b0,{DOUBLEWITHTWODWORDINTREE(0x49900000,0x00000000)}},
+        {VT_exponent,22,0x3a87b1,{DOUBLEWITHTWODWORDINTREE(0x49a00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b2,{DOUBLEWITHTWODWORDINTREE(0x49b00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b3,{DOUBLEWITHTWODWORDINTREE(0x49c00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b4,{DOUBLEWITHTWODWORDINTREE(0x49d00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b5,{DOUBLEWITHTWODWORDINTREE(0x49e00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b6,{DOUBLEWITHTWODWORDINTREE(0x49f00000,0x00000000)}},
+        {VT_exponent,22,0x3a87b7,{DOUBLEWITHTWODWORDINTREE(0x4a000000,0x00000000)}},
+        {VT_exponent,22,0x3a87b8,{DOUBLEWITHTWODWORDINTREE(0x4a100000,0x00000000)}},
+        {VT_exponent,22,0x3a87b9,{DOUBLEWITHTWODWORDINTREE(0x4a200000,0x00000000)}},
+        {VT_exponent,22,0x3a87ba,{DOUBLEWITHTWODWORDINTREE(0x4a300000,0x00000000)}},
+        {VT_exponent,22,0x3a87bb,{DOUBLEWITHTWODWORDINTREE(0x4a400000,0x00000000)}},
+        {VT_exponent,22,0x3a87bc,{DOUBLEWITHTWODWORDINTREE(0x4a500000,0x00000000)}},
+        {VT_exponent,22,0x3a87bd,{DOUBLEWITHTWODWORDINTREE(0x4a600000,0x00000000)}},
+        {VT_exponent,22,0x3a87be,{DOUBLEWITHTWODWORDINTREE(0x4a700000,0x00000000)}},
+        {VT_exponent,22,0x3a87bf,{DOUBLEWITHTWODWORDINTREE(0x4a800000,0x00000000)}},
+        {VT_exponent,22,0x3a87c0,{DOUBLEWITHTWODWORDINTREE(0x4a900000,0x00000000)}},
+        {VT_exponent,22,0x3a87c1,{DOUBLEWITHTWODWORDINTREE(0x4aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c2,{DOUBLEWITHTWODWORDINTREE(0x4ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c3,{DOUBLEWITHTWODWORDINTREE(0x4ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c4,{DOUBLEWITHTWODWORDINTREE(0x4ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c5,{DOUBLEWITHTWODWORDINTREE(0x4ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c6,{DOUBLEWITHTWODWORDINTREE(0x4af00000,0x00000000)}},
+        {VT_exponent,22,0x3a87c7,{DOUBLEWITHTWODWORDINTREE(0x4b000000,0x00000000)}},
+        {VT_exponent,22,0x3a87c8,{DOUBLEWITHTWODWORDINTREE(0x4b100000,0x00000000)}},
+        {VT_exponent,22,0x3a87c9,{DOUBLEWITHTWODWORDINTREE(0x4b200000,0x00000000)}},
+        {VT_exponent,22,0x3a87ca,{DOUBLEWITHTWODWORDINTREE(0x4b300000,0x00000000)}},
+        {VT_exponent,22,0x3a87cb,{DOUBLEWITHTWODWORDINTREE(0x4b400000,0x00000000)}},
+        {VT_exponent,22,0x3a87cc,{DOUBLEWITHTWODWORDINTREE(0x4b500000,0x00000000)}},
+        {VT_exponent,22,0x3a87cd,{DOUBLEWITHTWODWORDINTREE(0x4b600000,0x00000000)}},
+        {VT_exponent,22,0x3a87ce,{DOUBLEWITHTWODWORDINTREE(0x4b700000,0x00000000)}},
+        {VT_exponent,22,0x3a87cf,{DOUBLEWITHTWODWORDINTREE(0x4b800000,0x00000000)}},
+        {VT_exponent,22,0x3a87d0,{DOUBLEWITHTWODWORDINTREE(0x4b900000,0x00000000)}},
+        {VT_exponent,22,0x3a87d1,{DOUBLEWITHTWODWORDINTREE(0x4ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d2,{DOUBLEWITHTWODWORDINTREE(0x4bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d3,{DOUBLEWITHTWODWORDINTREE(0x4bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d4,{DOUBLEWITHTWODWORDINTREE(0x4bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d5,{DOUBLEWITHTWODWORDINTREE(0x4be00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d6,{DOUBLEWITHTWODWORDINTREE(0x4bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a87d7,{DOUBLEWITHTWODWORDINTREE(0x4c000000,0x00000000)}},
+        {VT_exponent,22,0x3a87d8,{DOUBLEWITHTWODWORDINTREE(0x4c100000,0x00000000)}},
+        {VT_exponent,22,0x3a87d9,{DOUBLEWITHTWODWORDINTREE(0x4c200000,0x00000000)}},
+        {VT_exponent,22,0x3a87da,{DOUBLEWITHTWODWORDINTREE(0x4c300000,0x00000000)}},
+        {VT_exponent,22,0x3a87db,{DOUBLEWITHTWODWORDINTREE(0x4c400000,0x00000000)}},
+        {VT_exponent,22,0x3a87dc,{DOUBLEWITHTWODWORDINTREE(0x4c500000,0x00000000)}},
+        {VT_exponent,22,0x3a87dd,{DOUBLEWITHTWODWORDINTREE(0x4c600000,0x00000000)}},
+        {VT_exponent,22,0x3a87de,{DOUBLEWITHTWODWORDINTREE(0x4c700000,0x00000000)}},
+        {VT_exponent,22,0x3a87df,{DOUBLEWITHTWODWORDINTREE(0x4c800000,0x00000000)}},
+        {VT_exponent,22,0x3a87e0,{DOUBLEWITHTWODWORDINTREE(0x4c900000,0x00000000)}},
+        {VT_exponent,22,0x3a87e1,{DOUBLEWITHTWODWORDINTREE(0x4ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e2,{DOUBLEWITHTWODWORDINTREE(0x4cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e3,{DOUBLEWITHTWODWORDINTREE(0x4cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e4,{DOUBLEWITHTWODWORDINTREE(0x4cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e5,{DOUBLEWITHTWODWORDINTREE(0x4ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e6,{DOUBLEWITHTWODWORDINTREE(0x4cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a87e7,{DOUBLEWITHTWODWORDINTREE(0x4d000000,0x00000000)}},
+        {VT_exponent,22,0x3a87e8,{DOUBLEWITHTWODWORDINTREE(0x4d100000,0x00000000)}},
+        {VT_exponent,22,0x3a87e9,{DOUBLEWITHTWODWORDINTREE(0x4d200000,0x00000000)}},
+        {VT_exponent,22,0x3a87ea,{DOUBLEWITHTWODWORDINTREE(0x4d300000,0x00000000)}},
+        {VT_exponent,22,0x3a87eb,{DOUBLEWITHTWODWORDINTREE(0x4d400000,0x00000000)}},
+        {VT_exponent,22,0x3a87ec,{DOUBLEWITHTWODWORDINTREE(0x4d500000,0x00000000)}},
+        {VT_exponent,22,0x3a87ed,{DOUBLEWITHTWODWORDINTREE(0x4d600000,0x00000000)}},
+        {VT_exponent,22,0x3a87ee,{DOUBLEWITHTWODWORDINTREE(0x4d700000,0x00000000)}},
+        {VT_exponent,22,0x3a87ef,{DOUBLEWITHTWODWORDINTREE(0x4d800000,0x00000000)}},
+        {VT_exponent,22,0x3a87f0,{DOUBLEWITHTWODWORDINTREE(0x4d900000,0x00000000)}},
+        {VT_exponent,22,0x3a87f1,{DOUBLEWITHTWODWORDINTREE(0x4da00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f2,{DOUBLEWITHTWODWORDINTREE(0x4db00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f3,{DOUBLEWITHTWODWORDINTREE(0x4dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f4,{DOUBLEWITHTWODWORDINTREE(0x4dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f5,{DOUBLEWITHTWODWORDINTREE(0x4de00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f6,{DOUBLEWITHTWODWORDINTREE(0x4df00000,0x00000000)}},
+        {VT_exponent,22,0x3a87f7,{DOUBLEWITHTWODWORDINTREE(0x4e000000,0x00000000)}},
+        {VT_exponent,22,0x3a87f8,{DOUBLEWITHTWODWORDINTREE(0x4e100000,0x00000000)}},
+        {VT_exponent,22,0x3a87f9,{DOUBLEWITHTWODWORDINTREE(0x4e200000,0x00000000)}},
+        {VT_exponent,22,0x3a87fa,{DOUBLEWITHTWODWORDINTREE(0x4e300000,0x00000000)}},
+        {VT_exponent,22,0x3a87fb,{DOUBLEWITHTWODWORDINTREE(0x4e400000,0x00000000)}},
+        {VT_exponent,22,0x3a87fc,{DOUBLEWITHTWODWORDINTREE(0x4e500000,0x00000000)}},
+        {VT_exponent,22,0x3a87fd,{DOUBLEWITHTWODWORDINTREE(0x4e600000,0x00000000)}},
+        {VT_exponent,22,0x3a87fe,{DOUBLEWITHTWODWORDINTREE(0x4e700000,0x00000000)}},
+        {VT_exponent,22,0x3a87ff,{DOUBLEWITHTWODWORDINTREE(0x4e800000,0x00000000)}},
+        {VT_exponent,22,0x3a9000,{DOUBLEWITHTWODWORDINTREE(0x4e900000,0x00000000)}},
+        {VT_exponent,22,0x3a9001,{DOUBLEWITHTWODWORDINTREE(0x4ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a9002,{DOUBLEWITHTWODWORDINTREE(0x4eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9003,{DOUBLEWITHTWODWORDINTREE(0x4ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a9004,{DOUBLEWITHTWODWORDINTREE(0x4ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a9005,{DOUBLEWITHTWODWORDINTREE(0x4ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a9006,{DOUBLEWITHTWODWORDINTREE(0x4ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a9007,{DOUBLEWITHTWODWORDINTREE(0x4f000000,0x00000000)}},
+        {VT_exponent,22,0x3a9008,{DOUBLEWITHTWODWORDINTREE(0x4f100000,0x00000000)}},
+        {VT_exponent,22,0x3a9009,{DOUBLEWITHTWODWORDINTREE(0x4f200000,0x00000000)}},
+        {VT_exponent,22,0x3a900a,{DOUBLEWITHTWODWORDINTREE(0x4f300000,0x00000000)}},
+        {VT_exponent,22,0x3a900b,{DOUBLEWITHTWODWORDINTREE(0x4f400000,0x00000000)}},
+        {VT_exponent,22,0x3a900c,{DOUBLEWITHTWODWORDINTREE(0x4f500000,0x00000000)}},
+        {VT_exponent,22,0x3a900d,{DOUBLEWITHTWODWORDINTREE(0x4f600000,0x00000000)}},
+        {VT_exponent,22,0x3a900e,{DOUBLEWITHTWODWORDINTREE(0x4f700000,0x00000000)}},
+        {VT_exponent,22,0x3a900f,{DOUBLEWITHTWODWORDINTREE(0x4f800000,0x00000000)}},
+        {VT_exponent,22,0x3a9010,{DOUBLEWITHTWODWORDINTREE(0x4f900000,0x00000000)}},
+        {VT_exponent,22,0x3a9011,{DOUBLEWITHTWODWORDINTREE(0x4fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a9012,{DOUBLEWITHTWODWORDINTREE(0x4fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9013,{DOUBLEWITHTWODWORDINTREE(0x4fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a9014,{DOUBLEWITHTWODWORDINTREE(0x4fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a9015,{DOUBLEWITHTWODWORDINTREE(0x4fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a9016,{DOUBLEWITHTWODWORDINTREE(0x4ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a9017,{DOUBLEWITHTWODWORDINTREE(0x50000000,0x00000000)}},
+        {VT_exponent,22,0x3a9018,{DOUBLEWITHTWODWORDINTREE(0x50100000,0x00000000)}},
+        {VT_exponent,22,0x3a9019,{DOUBLEWITHTWODWORDINTREE(0x50200000,0x00000000)}},
+        {VT_exponent,22,0x3a901a,{DOUBLEWITHTWODWORDINTREE(0x50300000,0x00000000)}},
+        {VT_exponent,22,0x3a901b,{DOUBLEWITHTWODWORDINTREE(0x50400000,0x00000000)}},
+        {VT_exponent,22,0x3a901c,{DOUBLEWITHTWODWORDINTREE(0x50500000,0x00000000)}},
+        {VT_exponent,22,0x3a901d,{DOUBLEWITHTWODWORDINTREE(0x50600000,0x00000000)}},
+        {VT_exponent,22,0x3a901e,{DOUBLEWITHTWODWORDINTREE(0x50700000,0x00000000)}},
+        {VT_exponent,22,0x3a901f,{DOUBLEWITHTWODWORDINTREE(0x50800000,0x00000000)}},
+        {VT_exponent,22,0x3a9020,{DOUBLEWITHTWODWORDINTREE(0x50900000,0x00000000)}},
+        {VT_exponent,22,0x3a9021,{DOUBLEWITHTWODWORDINTREE(0x50a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9022,{DOUBLEWITHTWODWORDINTREE(0x50b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9023,{DOUBLEWITHTWODWORDINTREE(0x50c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9024,{DOUBLEWITHTWODWORDINTREE(0x50d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9025,{DOUBLEWITHTWODWORDINTREE(0x50e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9026,{DOUBLEWITHTWODWORDINTREE(0x50f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9027,{DOUBLEWITHTWODWORDINTREE(0x51000000,0x00000000)}},
+        {VT_exponent,22,0x3a9028,{DOUBLEWITHTWODWORDINTREE(0x51100000,0x00000000)}},
+        {VT_exponent,22,0x3a9029,{DOUBLEWITHTWODWORDINTREE(0x51200000,0x00000000)}},
+        {VT_exponent,22,0x3a902a,{DOUBLEWITHTWODWORDINTREE(0x51300000,0x00000000)}},
+        {VT_exponent,22,0x3a902b,{DOUBLEWITHTWODWORDINTREE(0x51400000,0x00000000)}},
+        {VT_exponent,22,0x3a902c,{DOUBLEWITHTWODWORDINTREE(0x51500000,0x00000000)}},
+        {VT_exponent,22,0x3a902d,{DOUBLEWITHTWODWORDINTREE(0x51600000,0x00000000)}},
+        {VT_exponent,22,0x3a902e,{DOUBLEWITHTWODWORDINTREE(0x51700000,0x00000000)}},
+        {VT_exponent,22,0x3a902f,{DOUBLEWITHTWODWORDINTREE(0x51800000,0x00000000)}},
+        {VT_exponent,22,0x3a9030,{DOUBLEWITHTWODWORDINTREE(0x51900000,0x00000000)}},
+        {VT_exponent,22,0x3a9031,{DOUBLEWITHTWODWORDINTREE(0x51a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9032,{DOUBLEWITHTWODWORDINTREE(0x51b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9033,{DOUBLEWITHTWODWORDINTREE(0x51c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9034,{DOUBLEWITHTWODWORDINTREE(0x51d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9035,{DOUBLEWITHTWODWORDINTREE(0x51e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9036,{DOUBLEWITHTWODWORDINTREE(0x51f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9037,{DOUBLEWITHTWODWORDINTREE(0x52000000,0x00000000)}},
+        {VT_exponent,22,0x3a9038,{DOUBLEWITHTWODWORDINTREE(0x52100000,0x00000000)}},
+        {VT_exponent,22,0x3a9039,{DOUBLEWITHTWODWORDINTREE(0x52200000,0x00000000)}},
+        {VT_exponent,22,0x3a903a,{DOUBLEWITHTWODWORDINTREE(0x52300000,0x00000000)}},
+        {VT_exponent,22,0x3a903b,{DOUBLEWITHTWODWORDINTREE(0x52400000,0x00000000)}},
+        {VT_exponent,22,0x3a903c,{DOUBLEWITHTWODWORDINTREE(0x52500000,0x00000000)}},
+        {VT_exponent,22,0x3a903d,{DOUBLEWITHTWODWORDINTREE(0x52600000,0x00000000)}},
+        {VT_exponent,22,0x3a903e,{DOUBLEWITHTWODWORDINTREE(0x52700000,0x00000000)}},
+        {VT_exponent,22,0x3a903f,{DOUBLEWITHTWODWORDINTREE(0x52800000,0x00000000)}},
+        {VT_exponent,22,0x3a9040,{DOUBLEWITHTWODWORDINTREE(0x52900000,0x00000000)}},
+        {VT_exponent,22,0x3a9041,{DOUBLEWITHTWODWORDINTREE(0x52a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9042,{DOUBLEWITHTWODWORDINTREE(0x52b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9043,{DOUBLEWITHTWODWORDINTREE(0x52c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9044,{DOUBLEWITHTWODWORDINTREE(0x52d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9045,{DOUBLEWITHTWODWORDINTREE(0x52e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9046,{DOUBLEWITHTWODWORDINTREE(0x52f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9047,{DOUBLEWITHTWODWORDINTREE(0x53000000,0x00000000)}},
+        {VT_exponent,22,0x3a9048,{DOUBLEWITHTWODWORDINTREE(0x53100000,0x00000000)}},
+        {VT_exponent,22,0x3a9049,{DOUBLEWITHTWODWORDINTREE(0x53200000,0x00000000)}},
+        {VT_exponent,22,0x3a904a,{DOUBLEWITHTWODWORDINTREE(0x53300000,0x00000000)}},
+        {VT_exponent,22,0x3a904b,{DOUBLEWITHTWODWORDINTREE(0x53400000,0x00000000)}},
+        {VT_exponent,22,0x3a904c,{DOUBLEWITHTWODWORDINTREE(0x53500000,0x00000000)}},
+        {VT_exponent,22,0x3a904d,{DOUBLEWITHTWODWORDINTREE(0x53600000,0x00000000)}},
+        {VT_exponent,22,0x3a904e,{DOUBLEWITHTWODWORDINTREE(0x53700000,0x00000000)}},
+        {VT_exponent,22,0x3a904f,{DOUBLEWITHTWODWORDINTREE(0x53800000,0x00000000)}},
+        {VT_exponent,22,0x3a9050,{DOUBLEWITHTWODWORDINTREE(0x53900000,0x00000000)}},
+        {VT_exponent,22,0x3a9051,{DOUBLEWITHTWODWORDINTREE(0x53a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9052,{DOUBLEWITHTWODWORDINTREE(0x53b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9053,{DOUBLEWITHTWODWORDINTREE(0x53c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9054,{DOUBLEWITHTWODWORDINTREE(0x53d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9055,{DOUBLEWITHTWODWORDINTREE(0x53e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9056,{DOUBLEWITHTWODWORDINTREE(0x53f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9057,{DOUBLEWITHTWODWORDINTREE(0x54000000,0x00000000)}},
+        {VT_exponent,22,0x3a9058,{DOUBLEWITHTWODWORDINTREE(0x54100000,0x00000000)}},
+        {VT_exponent,22,0x3a9059,{DOUBLEWITHTWODWORDINTREE(0x54200000,0x00000000)}},
+        {VT_exponent,22,0x3a905a,{DOUBLEWITHTWODWORDINTREE(0x54300000,0x00000000)}},
+        {VT_exponent,22,0x3a905b,{DOUBLEWITHTWODWORDINTREE(0x54400000,0x00000000)}},
+        {VT_exponent,22,0x3a905c,{DOUBLEWITHTWODWORDINTREE(0x54500000,0x00000000)}},
+        {VT_exponent,22,0x3a905d,{DOUBLEWITHTWODWORDINTREE(0x54600000,0x00000000)}},
+        {VT_exponent,22,0x3a905e,{DOUBLEWITHTWODWORDINTREE(0x54700000,0x00000000)}},
+        {VT_exponent,22,0x3a905f,{DOUBLEWITHTWODWORDINTREE(0x54800000,0x00000000)}},
+        {VT_exponent,22,0x3a9060,{DOUBLEWITHTWODWORDINTREE(0x54900000,0x00000000)}},
+        {VT_exponent,22,0x3a9061,{DOUBLEWITHTWODWORDINTREE(0x54a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9062,{DOUBLEWITHTWODWORDINTREE(0x54b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9063,{DOUBLEWITHTWODWORDINTREE(0x54c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9064,{DOUBLEWITHTWODWORDINTREE(0x54d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9065,{DOUBLEWITHTWODWORDINTREE(0x54e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9066,{DOUBLEWITHTWODWORDINTREE(0x54f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9067,{DOUBLEWITHTWODWORDINTREE(0x55000000,0x00000000)}},
+        {VT_exponent,22,0x3a9068,{DOUBLEWITHTWODWORDINTREE(0x55100000,0x00000000)}},
+        {VT_exponent,22,0x3a9069,{DOUBLEWITHTWODWORDINTREE(0x55200000,0x00000000)}},
+        {VT_exponent,22,0x3a906a,{DOUBLEWITHTWODWORDINTREE(0x55300000,0x00000000)}},
+        {VT_exponent,22,0x3a906b,{DOUBLEWITHTWODWORDINTREE(0x55400000,0x00000000)}},
+        {VT_exponent,22,0x3a906c,{DOUBLEWITHTWODWORDINTREE(0x55500000,0x00000000)}},
+        {VT_exponent,22,0x3a906d,{DOUBLEWITHTWODWORDINTREE(0x55600000,0x00000000)}},
+        {VT_exponent,22,0x3a906e,{DOUBLEWITHTWODWORDINTREE(0x55700000,0x00000000)}},
+        {VT_exponent,22,0x3a906f,{DOUBLEWITHTWODWORDINTREE(0x55800000,0x00000000)}},
+        {VT_exponent,22,0x3a9070,{DOUBLEWITHTWODWORDINTREE(0x55900000,0x00000000)}},
+        {VT_exponent,22,0x3a9071,{DOUBLEWITHTWODWORDINTREE(0x55a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9072,{DOUBLEWITHTWODWORDINTREE(0x55b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9073,{DOUBLEWITHTWODWORDINTREE(0x55c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9074,{DOUBLEWITHTWODWORDINTREE(0x55d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9075,{DOUBLEWITHTWODWORDINTREE(0x55e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9076,{DOUBLEWITHTWODWORDINTREE(0x55f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9077,{DOUBLEWITHTWODWORDINTREE(0x56000000,0x00000000)}},
+        {VT_exponent,22,0x3a9078,{DOUBLEWITHTWODWORDINTREE(0x56100000,0x00000000)}},
+        {VT_exponent,22,0x3a9079,{DOUBLEWITHTWODWORDINTREE(0x56200000,0x00000000)}},
+        {VT_exponent,22,0x3a907a,{DOUBLEWITHTWODWORDINTREE(0x56300000,0x00000000)}},
+        {VT_exponent,22,0x3a907b,{DOUBLEWITHTWODWORDINTREE(0x56400000,0x00000000)}},
+        {VT_exponent,22,0x3a907c,{DOUBLEWITHTWODWORDINTREE(0x56500000,0x00000000)}},
+        {VT_exponent,22,0x3a907d,{DOUBLEWITHTWODWORDINTREE(0x56600000,0x00000000)}},
+        {VT_exponent,22,0x3a907e,{DOUBLEWITHTWODWORDINTREE(0x56700000,0x00000000)}},
+        {VT_exponent,22,0x3a907f,{DOUBLEWITHTWODWORDINTREE(0x56800000,0x00000000)}},
+        {VT_exponent,22,0x3a9080,{DOUBLEWITHTWODWORDINTREE(0x56900000,0x00000000)}},
+        {VT_exponent,22,0x3a9081,{DOUBLEWITHTWODWORDINTREE(0x56a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9082,{DOUBLEWITHTWODWORDINTREE(0x56b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9083,{DOUBLEWITHTWODWORDINTREE(0x56c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9084,{DOUBLEWITHTWODWORDINTREE(0x56d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9085,{DOUBLEWITHTWODWORDINTREE(0x56e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9086,{DOUBLEWITHTWODWORDINTREE(0x56f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9087,{DOUBLEWITHTWODWORDINTREE(0x57000000,0x00000000)}},
+        {VT_exponent,22,0x3a9088,{DOUBLEWITHTWODWORDINTREE(0x57100000,0x00000000)}},
+        {VT_exponent,22,0x3a9089,{DOUBLEWITHTWODWORDINTREE(0x57200000,0x00000000)}},
+        {VT_exponent,22,0x3a908a,{DOUBLEWITHTWODWORDINTREE(0x57300000,0x00000000)}},
+        {VT_exponent,22,0x3a908b,{DOUBLEWITHTWODWORDINTREE(0x57400000,0x00000000)}},
+        {VT_exponent,22,0x3a908c,{DOUBLEWITHTWODWORDINTREE(0x57500000,0x00000000)}},
+        {VT_exponent,22,0x3a908d,{DOUBLEWITHTWODWORDINTREE(0x57600000,0x00000000)}},
+        {VT_exponent,22,0x3a908e,{DOUBLEWITHTWODWORDINTREE(0x57700000,0x00000000)}},
+        {VT_exponent,22,0x3a908f,{DOUBLEWITHTWODWORDINTREE(0x57800000,0x00000000)}},
+        {VT_exponent,22,0x3a9090,{DOUBLEWITHTWODWORDINTREE(0x57900000,0x00000000)}},
+        {VT_exponent,22,0x3a9091,{DOUBLEWITHTWODWORDINTREE(0x57a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9092,{DOUBLEWITHTWODWORDINTREE(0x57b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9093,{DOUBLEWITHTWODWORDINTREE(0x57c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9094,{DOUBLEWITHTWODWORDINTREE(0x57d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9095,{DOUBLEWITHTWODWORDINTREE(0x57e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9096,{DOUBLEWITHTWODWORDINTREE(0x57f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9097,{DOUBLEWITHTWODWORDINTREE(0x58000000,0x00000000)}},
+        {VT_exponent,22,0x3a9098,{DOUBLEWITHTWODWORDINTREE(0x58100000,0x00000000)}},
+        {VT_exponent,22,0x3a9099,{DOUBLEWITHTWODWORDINTREE(0x58200000,0x00000000)}},
+        {VT_exponent,22,0x3a909a,{DOUBLEWITHTWODWORDINTREE(0x58300000,0x00000000)}},
+        {VT_exponent,22,0x3a909b,{DOUBLEWITHTWODWORDINTREE(0x58400000,0x00000000)}},
+        {VT_exponent,22,0x3a909c,{DOUBLEWITHTWODWORDINTREE(0x58500000,0x00000000)}},
+        {VT_exponent,22,0x3a909d,{DOUBLEWITHTWODWORDINTREE(0x58600000,0x00000000)}},
+        {VT_exponent,22,0x3a909e,{DOUBLEWITHTWODWORDINTREE(0x58700000,0x00000000)}},
+        {VT_exponent,22,0x3a909f,{DOUBLEWITHTWODWORDINTREE(0x58800000,0x00000000)}},
+        {VT_exponent,22,0x3a90a0,{DOUBLEWITHTWODWORDINTREE(0x58900000,0x00000000)}},
+        {VT_exponent,22,0x3a90a1,{DOUBLEWITHTWODWORDINTREE(0x58a00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a2,{DOUBLEWITHTWODWORDINTREE(0x58b00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a3,{DOUBLEWITHTWODWORDINTREE(0x58c00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a4,{DOUBLEWITHTWODWORDINTREE(0x58d00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a5,{DOUBLEWITHTWODWORDINTREE(0x58e00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a6,{DOUBLEWITHTWODWORDINTREE(0x58f00000,0x00000000)}},
+        {VT_exponent,22,0x3a90a7,{DOUBLEWITHTWODWORDINTREE(0x59000000,0x00000000)}},
+        {VT_exponent,22,0x3a90a8,{DOUBLEWITHTWODWORDINTREE(0x59100000,0x00000000)}},
+        {VT_exponent,22,0x3a90a9,{DOUBLEWITHTWODWORDINTREE(0x59200000,0x00000000)}},
+        {VT_exponent,22,0x3a90aa,{DOUBLEWITHTWODWORDINTREE(0x59300000,0x00000000)}},
+        {VT_exponent,22,0x3a90ab,{DOUBLEWITHTWODWORDINTREE(0x59400000,0x00000000)}},
+        {VT_exponent,22,0x3a90ac,{DOUBLEWITHTWODWORDINTREE(0x59500000,0x00000000)}},
+        {VT_exponent,22,0x3a90ad,{DOUBLEWITHTWODWORDINTREE(0x59600000,0x00000000)}},
+        {VT_exponent,22,0x3a90ae,{DOUBLEWITHTWODWORDINTREE(0x59700000,0x00000000)}},
+        {VT_exponent,22,0x3a90af,{DOUBLEWITHTWODWORDINTREE(0x59800000,0x00000000)}},
+        {VT_exponent,22,0x3a90b0,{DOUBLEWITHTWODWORDINTREE(0x59900000,0x00000000)}},
+        {VT_exponent,22,0x3a90b1,{DOUBLEWITHTWODWORDINTREE(0x59a00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b2,{DOUBLEWITHTWODWORDINTREE(0x59b00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b3,{DOUBLEWITHTWODWORDINTREE(0x59c00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b4,{DOUBLEWITHTWODWORDINTREE(0x59d00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b5,{DOUBLEWITHTWODWORDINTREE(0x59e00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b6,{DOUBLEWITHTWODWORDINTREE(0x59f00000,0x00000000)}},
+        {VT_exponent,22,0x3a90b7,{DOUBLEWITHTWODWORDINTREE(0x5a000000,0x00000000)}},
+        {VT_exponent,22,0x3a90b8,{DOUBLEWITHTWODWORDINTREE(0x5a100000,0x00000000)}},
+        {VT_exponent,22,0x3a90b9,{DOUBLEWITHTWODWORDINTREE(0x5a200000,0x00000000)}},
+        {VT_exponent,22,0x3a90ba,{DOUBLEWITHTWODWORDINTREE(0x5a300000,0x00000000)}},
+        {VT_exponent,22,0x3a90bb,{DOUBLEWITHTWODWORDINTREE(0x5a400000,0x00000000)}},
+        {VT_exponent,22,0x3a90bc,{DOUBLEWITHTWODWORDINTREE(0x5a500000,0x00000000)}},
+        {VT_exponent,22,0x3a90bd,{DOUBLEWITHTWODWORDINTREE(0x5a600000,0x00000000)}},
+        {VT_exponent,22,0x3a90be,{DOUBLEWITHTWODWORDINTREE(0x5a700000,0x00000000)}},
+        {VT_exponent,22,0x3a90bf,{DOUBLEWITHTWODWORDINTREE(0x5a800000,0x00000000)}},
+        {VT_exponent,22,0x3a90c0,{DOUBLEWITHTWODWORDINTREE(0x5a900000,0x00000000)}},
+        {VT_exponent,22,0x3a90c1,{DOUBLEWITHTWODWORDINTREE(0x5aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c2,{DOUBLEWITHTWODWORDINTREE(0x5ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c3,{DOUBLEWITHTWODWORDINTREE(0x5ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c4,{DOUBLEWITHTWODWORDINTREE(0x5ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c5,{DOUBLEWITHTWODWORDINTREE(0x5ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c6,{DOUBLEWITHTWODWORDINTREE(0x5af00000,0x00000000)}},
+        {VT_exponent,22,0x3a90c7,{DOUBLEWITHTWODWORDINTREE(0x5b000000,0x00000000)}},
+        {VT_exponent,22,0x3a90c8,{DOUBLEWITHTWODWORDINTREE(0x5b100000,0x00000000)}},
+        {VT_exponent,22,0x3a90c9,{DOUBLEWITHTWODWORDINTREE(0x5b200000,0x00000000)}},
+        {VT_exponent,22,0x3a90ca,{DOUBLEWITHTWODWORDINTREE(0x5b300000,0x00000000)}},
+        {VT_exponent,22,0x3a90cb,{DOUBLEWITHTWODWORDINTREE(0x5b400000,0x00000000)}},
+        {VT_exponent,22,0x3a90cc,{DOUBLEWITHTWODWORDINTREE(0x5b500000,0x00000000)}},
+        {VT_exponent,22,0x3a90cd,{DOUBLEWITHTWODWORDINTREE(0x5b600000,0x00000000)}},
+        {VT_exponent,22,0x3a90ce,{DOUBLEWITHTWODWORDINTREE(0x5b700000,0x00000000)}},
+        {VT_exponent,22,0x3a90cf,{DOUBLEWITHTWODWORDINTREE(0x5b800000,0x00000000)}},
+        {VT_exponent,22,0x3a90d0,{DOUBLEWITHTWODWORDINTREE(0x5b900000,0x00000000)}},
+        {VT_exponent,22,0x3a90d1,{DOUBLEWITHTWODWORDINTREE(0x5ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d2,{DOUBLEWITHTWODWORDINTREE(0x5bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d3,{DOUBLEWITHTWODWORDINTREE(0x5bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d4,{DOUBLEWITHTWODWORDINTREE(0x5bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d5,{DOUBLEWITHTWODWORDINTREE(0x5be00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d6,{DOUBLEWITHTWODWORDINTREE(0x5bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a90d7,{DOUBLEWITHTWODWORDINTREE(0x5c000000,0x00000000)}},
+        {VT_exponent,22,0x3a90d8,{DOUBLEWITHTWODWORDINTREE(0x5c100000,0x00000000)}},
+        {VT_exponent,22,0x3a90d9,{DOUBLEWITHTWODWORDINTREE(0x5c200000,0x00000000)}},
+        {VT_exponent,22,0x3a90da,{DOUBLEWITHTWODWORDINTREE(0x5c300000,0x00000000)}},
+        {VT_exponent,22,0x3a90db,{DOUBLEWITHTWODWORDINTREE(0x5c400000,0x00000000)}},
+        {VT_exponent,22,0x3a90dc,{DOUBLEWITHTWODWORDINTREE(0x5c500000,0x00000000)}},
+        {VT_exponent,22,0x3a90dd,{DOUBLEWITHTWODWORDINTREE(0x5c600000,0x00000000)}},
+        {VT_exponent,22,0x3a90de,{DOUBLEWITHTWODWORDINTREE(0x5c700000,0x00000000)}},
+        {VT_exponent,22,0x3a90df,{DOUBLEWITHTWODWORDINTREE(0x5c800000,0x00000000)}},
+        {VT_exponent,22,0x3a90e0,{DOUBLEWITHTWODWORDINTREE(0x5c900000,0x00000000)}},
+        {VT_exponent,22,0x3a90e1,{DOUBLEWITHTWODWORDINTREE(0x5ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e2,{DOUBLEWITHTWODWORDINTREE(0x5cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e3,{DOUBLEWITHTWODWORDINTREE(0x5cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e4,{DOUBLEWITHTWODWORDINTREE(0x5cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e5,{DOUBLEWITHTWODWORDINTREE(0x5ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e6,{DOUBLEWITHTWODWORDINTREE(0x5cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a90e7,{DOUBLEWITHTWODWORDINTREE(0x5d000000,0x00000000)}},
+        {VT_exponent,22,0x3a90e8,{DOUBLEWITHTWODWORDINTREE(0x5d100000,0x00000000)}},
+        {VT_exponent,22,0x3a90e9,{DOUBLEWITHTWODWORDINTREE(0x5d200000,0x00000000)}},
+        {VT_exponent,22,0x3a90ea,{DOUBLEWITHTWODWORDINTREE(0x5d300000,0x00000000)}},
+        {VT_exponent,22,0x3a90eb,{DOUBLEWITHTWODWORDINTREE(0x5d400000,0x00000000)}},
+        {VT_exponent,22,0x3a90ec,{DOUBLEWITHTWODWORDINTREE(0x5d500000,0x00000000)}},
+        {VT_exponent,22,0x3a90ed,{DOUBLEWITHTWODWORDINTREE(0x5d600000,0x00000000)}},
+        {VT_exponent,22,0x3a90ee,{DOUBLEWITHTWODWORDINTREE(0x5d700000,0x00000000)}},
+        {VT_exponent,22,0x3a90ef,{DOUBLEWITHTWODWORDINTREE(0x5d800000,0x00000000)}},
+        {VT_exponent,22,0x3a90f0,{DOUBLEWITHTWODWORDINTREE(0x5d900000,0x00000000)}},
+        {VT_exponent,22,0x3a90f1,{DOUBLEWITHTWODWORDINTREE(0x5da00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f2,{DOUBLEWITHTWODWORDINTREE(0x5db00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f3,{DOUBLEWITHTWODWORDINTREE(0x5dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f4,{DOUBLEWITHTWODWORDINTREE(0x5dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f5,{DOUBLEWITHTWODWORDINTREE(0x5de00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f6,{DOUBLEWITHTWODWORDINTREE(0x5df00000,0x00000000)}},
+        {VT_exponent,22,0x3a90f7,{DOUBLEWITHTWODWORDINTREE(0x5e000000,0x00000000)}},
+        {VT_exponent,22,0x3a90f8,{DOUBLEWITHTWODWORDINTREE(0x5e100000,0x00000000)}},
+        {VT_exponent,22,0x3a90f9,{DOUBLEWITHTWODWORDINTREE(0x5e200000,0x00000000)}},
+        {VT_exponent,22,0x3a90fa,{DOUBLEWITHTWODWORDINTREE(0x5e300000,0x00000000)}},
+        {VT_exponent,22,0x3a90fb,{DOUBLEWITHTWODWORDINTREE(0x5e400000,0x00000000)}},
+        {VT_exponent,22,0x3a90fc,{DOUBLEWITHTWODWORDINTREE(0x5e500000,0x00000000)}},
+        {VT_exponent,22,0x3a90fd,{DOUBLEWITHTWODWORDINTREE(0x5e600000,0x00000000)}},
+        {VT_exponent,22,0x3a90fe,{DOUBLEWITHTWODWORDINTREE(0x5e700000,0x00000000)}},
+        {VT_exponent,22,0x3a90ff,{DOUBLEWITHTWODWORDINTREE(0x5e800000,0x00000000)}},
+        {VT_exponent,22,0x3a9100,{DOUBLEWITHTWODWORDINTREE(0x5e900000,0x00000000)}},
+        {VT_exponent,22,0x3a9101,{DOUBLEWITHTWODWORDINTREE(0x5ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a9102,{DOUBLEWITHTWODWORDINTREE(0x5eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9103,{DOUBLEWITHTWODWORDINTREE(0x5ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a9104,{DOUBLEWITHTWODWORDINTREE(0x5ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a9105,{DOUBLEWITHTWODWORDINTREE(0x5ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a9106,{DOUBLEWITHTWODWORDINTREE(0x5ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a9107,{DOUBLEWITHTWODWORDINTREE(0x5f000000,0x00000000)}},
+        {VT_exponent,22,0x3a9108,{DOUBLEWITHTWODWORDINTREE(0x5f100000,0x00000000)}},
+        {VT_exponent,22,0x3a9109,{DOUBLEWITHTWODWORDINTREE(0x5f200000,0x00000000)}},
+        {VT_exponent,22,0x3a910a,{DOUBLEWITHTWODWORDINTREE(0x5f300000,0x00000000)}},
+        {VT_exponent,22,0x3a910b,{DOUBLEWITHTWODWORDINTREE(0x5f400000,0x00000000)}},
+        {VT_exponent,22,0x3a910c,{DOUBLEWITHTWODWORDINTREE(0x5f500000,0x00000000)}},
+        {VT_exponent,22,0x3a910d,{DOUBLEWITHTWODWORDINTREE(0x5f600000,0x00000000)}},
+        {VT_exponent,22,0x3a910e,{DOUBLEWITHTWODWORDINTREE(0x5f700000,0x00000000)}},
+        {VT_exponent,22,0x3a910f,{DOUBLEWITHTWODWORDINTREE(0x5f800000,0x00000000)}},
+        {VT_exponent,22,0x3a9110,{DOUBLEWITHTWODWORDINTREE(0x5f900000,0x00000000)}},
+        {VT_exponent,22,0x3a9111,{DOUBLEWITHTWODWORDINTREE(0x5fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a9112,{DOUBLEWITHTWODWORDINTREE(0x5fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9113,{DOUBLEWITHTWODWORDINTREE(0x5fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a9114,{DOUBLEWITHTWODWORDINTREE(0x5fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a9115,{DOUBLEWITHTWODWORDINTREE(0x5fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a9116,{DOUBLEWITHTWODWORDINTREE(0x5ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a9117,{DOUBLEWITHTWODWORDINTREE(0x60000000,0x00000000)}},
+        {VT_exponent,22,0x3a9118,{DOUBLEWITHTWODWORDINTREE(0x60100000,0x00000000)}},
+        {VT_exponent,22,0x3a9119,{DOUBLEWITHTWODWORDINTREE(0x60200000,0x00000000)}},
+        {VT_exponent,22,0x3a911a,{DOUBLEWITHTWODWORDINTREE(0x60300000,0x00000000)}},
+        {VT_exponent,22,0x3a911b,{DOUBLEWITHTWODWORDINTREE(0x60400000,0x00000000)}},
+        {VT_exponent,22,0x3a911c,{DOUBLEWITHTWODWORDINTREE(0x60500000,0x00000000)}},
+        {VT_exponent,22,0x3a911d,{DOUBLEWITHTWODWORDINTREE(0x60600000,0x00000000)}},
+        {VT_exponent,22,0x3a911e,{DOUBLEWITHTWODWORDINTREE(0x60700000,0x00000000)}},
+        {VT_exponent,22,0x3a911f,{DOUBLEWITHTWODWORDINTREE(0x60800000,0x00000000)}},
+        {VT_exponent,22,0x3a9120,{DOUBLEWITHTWODWORDINTREE(0x60900000,0x00000000)}},
+        {VT_exponent,22,0x3a9121,{DOUBLEWITHTWODWORDINTREE(0x60a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9122,{DOUBLEWITHTWODWORDINTREE(0x60b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9123,{DOUBLEWITHTWODWORDINTREE(0x60c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9124,{DOUBLEWITHTWODWORDINTREE(0x60d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9125,{DOUBLEWITHTWODWORDINTREE(0x60e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9126,{DOUBLEWITHTWODWORDINTREE(0x60f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9127,{DOUBLEWITHTWODWORDINTREE(0x61000000,0x00000000)}},
+        {VT_exponent,22,0x3a9128,{DOUBLEWITHTWODWORDINTREE(0x61100000,0x00000000)}},
+        {VT_exponent,22,0x3a9129,{DOUBLEWITHTWODWORDINTREE(0x61200000,0x00000000)}},
+        {VT_exponent,22,0x3a912a,{DOUBLEWITHTWODWORDINTREE(0x61300000,0x00000000)}},
+        {VT_exponent,22,0x3a912b,{DOUBLEWITHTWODWORDINTREE(0x61400000,0x00000000)}},
+        {VT_exponent,22,0x3a912c,{DOUBLEWITHTWODWORDINTREE(0x61500000,0x00000000)}},
+        {VT_exponent,22,0x3a912d,{DOUBLEWITHTWODWORDINTREE(0x61600000,0x00000000)}},
+        {VT_exponent,22,0x3a912e,{DOUBLEWITHTWODWORDINTREE(0x61700000,0x00000000)}},
+        {VT_exponent,22,0x3a912f,{DOUBLEWITHTWODWORDINTREE(0x61800000,0x00000000)}},
+        {VT_exponent,22,0x3a9130,{DOUBLEWITHTWODWORDINTREE(0x61900000,0x00000000)}},
+        {VT_exponent,22,0x3a9131,{DOUBLEWITHTWODWORDINTREE(0x61a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9132,{DOUBLEWITHTWODWORDINTREE(0x61b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9133,{DOUBLEWITHTWODWORDINTREE(0x61c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9134,{DOUBLEWITHTWODWORDINTREE(0x61d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9135,{DOUBLEWITHTWODWORDINTREE(0x61e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9136,{DOUBLEWITHTWODWORDINTREE(0x61f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9137,{DOUBLEWITHTWODWORDINTREE(0x62000000,0x00000000)}},
+        {VT_exponent,22,0x3a9138,{DOUBLEWITHTWODWORDINTREE(0x62100000,0x00000000)}},
+        {VT_exponent,22,0x3a9139,{DOUBLEWITHTWODWORDINTREE(0x62200000,0x00000000)}},
+        {VT_exponent,22,0x3a913a,{DOUBLEWITHTWODWORDINTREE(0x62300000,0x00000000)}},
+        {VT_exponent,22,0x3a913b,{DOUBLEWITHTWODWORDINTREE(0x62400000,0x00000000)}},
+        {VT_exponent,22,0x3a913c,{DOUBLEWITHTWODWORDINTREE(0x62500000,0x00000000)}},
+        {VT_exponent,22,0x3a913d,{DOUBLEWITHTWODWORDINTREE(0x62600000,0x00000000)}},
+        {VT_exponent,22,0x3a913e,{DOUBLEWITHTWODWORDINTREE(0x62700000,0x00000000)}},
+        {VT_exponent,22,0x3a913f,{DOUBLEWITHTWODWORDINTREE(0x62800000,0x00000000)}},
+        {VT_exponent,22,0x3a9140,{DOUBLEWITHTWODWORDINTREE(0x62900000,0x00000000)}},
+        {VT_exponent,22,0x3a9141,{DOUBLEWITHTWODWORDINTREE(0x62a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9142,{DOUBLEWITHTWODWORDINTREE(0x62b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9143,{DOUBLEWITHTWODWORDINTREE(0x62c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9144,{DOUBLEWITHTWODWORDINTREE(0x62d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9145,{DOUBLEWITHTWODWORDINTREE(0x62e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9146,{DOUBLEWITHTWODWORDINTREE(0x62f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9147,{DOUBLEWITHTWODWORDINTREE(0x63000000,0x00000000)}},
+        {VT_exponent,22,0x3a9148,{DOUBLEWITHTWODWORDINTREE(0x63100000,0x00000000)}},
+        {VT_exponent,22,0x3a9149,{DOUBLEWITHTWODWORDINTREE(0x63200000,0x00000000)}},
+        {VT_exponent,22,0x3a914a,{DOUBLEWITHTWODWORDINTREE(0x63300000,0x00000000)}},
+        {VT_exponent,22,0x3a914b,{DOUBLEWITHTWODWORDINTREE(0x63400000,0x00000000)}},
+        {VT_exponent,22,0x3a914c,{DOUBLEWITHTWODWORDINTREE(0x63500000,0x00000000)}},
+        {VT_exponent,22,0x3a914d,{DOUBLEWITHTWODWORDINTREE(0x63600000,0x00000000)}},
+        {VT_exponent,22,0x3a914e,{DOUBLEWITHTWODWORDINTREE(0x63700000,0x00000000)}},
+        {VT_exponent,22,0x3a914f,{DOUBLEWITHTWODWORDINTREE(0x63800000,0x00000000)}},
+        {VT_exponent,22,0x3a9150,{DOUBLEWITHTWODWORDINTREE(0x63900000,0x00000000)}},
+        {VT_exponent,22,0x3a9151,{DOUBLEWITHTWODWORDINTREE(0x63a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9152,{DOUBLEWITHTWODWORDINTREE(0x63b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9153,{DOUBLEWITHTWODWORDINTREE(0x63c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9154,{DOUBLEWITHTWODWORDINTREE(0x63d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9155,{DOUBLEWITHTWODWORDINTREE(0x63e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9156,{DOUBLEWITHTWODWORDINTREE(0x63f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9157,{DOUBLEWITHTWODWORDINTREE(0x64000000,0x00000000)}},
+        {VT_exponent,22,0x3a9158,{DOUBLEWITHTWODWORDINTREE(0x64100000,0x00000000)}},
+        {VT_exponent,22,0x3a9159,{DOUBLEWITHTWODWORDINTREE(0x64200000,0x00000000)}},
+        {VT_exponent,22,0x3a915a,{DOUBLEWITHTWODWORDINTREE(0x64300000,0x00000000)}},
+        {VT_exponent,22,0x3a915b,{DOUBLEWITHTWODWORDINTREE(0x64400000,0x00000000)}},
+        {VT_exponent,22,0x3a915c,{DOUBLEWITHTWODWORDINTREE(0x64500000,0x00000000)}},
+        {VT_exponent,22,0x3a915d,{DOUBLEWITHTWODWORDINTREE(0x64600000,0x00000000)}},
+        {VT_exponent,22,0x3a915e,{DOUBLEWITHTWODWORDINTREE(0x64700000,0x00000000)}},
+        {VT_exponent,22,0x3a915f,{DOUBLEWITHTWODWORDINTREE(0x64800000,0x00000000)}},
+        {VT_exponent,22,0x3a9160,{DOUBLEWITHTWODWORDINTREE(0x64900000,0x00000000)}},
+        {VT_exponent,22,0x3a9161,{DOUBLEWITHTWODWORDINTREE(0x64a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9162,{DOUBLEWITHTWODWORDINTREE(0x64b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9163,{DOUBLEWITHTWODWORDINTREE(0x64c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9164,{DOUBLEWITHTWODWORDINTREE(0x64d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9165,{DOUBLEWITHTWODWORDINTREE(0x64e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9166,{DOUBLEWITHTWODWORDINTREE(0x64f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9167,{DOUBLEWITHTWODWORDINTREE(0x65000000,0x00000000)}},
+        {VT_exponent,22,0x3a9168,{DOUBLEWITHTWODWORDINTREE(0x65100000,0x00000000)}},
+        {VT_exponent,22,0x3a9169,{DOUBLEWITHTWODWORDINTREE(0x65200000,0x00000000)}},
+        {VT_exponent,22,0x3a916a,{DOUBLEWITHTWODWORDINTREE(0x65300000,0x00000000)}},
+        {VT_exponent,22,0x3a916b,{DOUBLEWITHTWODWORDINTREE(0x65400000,0x00000000)}},
+        {VT_exponent,22,0x3a916c,{DOUBLEWITHTWODWORDINTREE(0x65500000,0x00000000)}},
+        {VT_exponent,22,0x3a916d,{DOUBLEWITHTWODWORDINTREE(0x65600000,0x00000000)}},
+        {VT_exponent,22,0x3a916e,{DOUBLEWITHTWODWORDINTREE(0x65700000,0x00000000)}},
+        {VT_exponent,22,0x3a916f,{DOUBLEWITHTWODWORDINTREE(0x65800000,0x00000000)}},
+        {VT_exponent,22,0x3a9170,{DOUBLEWITHTWODWORDINTREE(0x65900000,0x00000000)}},
+        {VT_exponent,22,0x3a9171,{DOUBLEWITHTWODWORDINTREE(0x65a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9172,{DOUBLEWITHTWODWORDINTREE(0x65b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9173,{DOUBLEWITHTWODWORDINTREE(0x65c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9174,{DOUBLEWITHTWODWORDINTREE(0x65d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9175,{DOUBLEWITHTWODWORDINTREE(0x65e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9176,{DOUBLEWITHTWODWORDINTREE(0x65f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9177,{DOUBLEWITHTWODWORDINTREE(0x66000000,0x00000000)}},
+        {VT_exponent,22,0x3a9178,{DOUBLEWITHTWODWORDINTREE(0x66100000,0x00000000)}},
+        {VT_exponent,22,0x3a9179,{DOUBLEWITHTWODWORDINTREE(0x66200000,0x00000000)}},
+        {VT_exponent,22,0x3a917a,{DOUBLEWITHTWODWORDINTREE(0x66300000,0x00000000)}},
+        {VT_exponent,22,0x3a917b,{DOUBLEWITHTWODWORDINTREE(0x66400000,0x00000000)}},
+        {VT_exponent,22,0x3a917c,{DOUBLEWITHTWODWORDINTREE(0x66500000,0x00000000)}},
+        {VT_exponent,22,0x3a917d,{DOUBLEWITHTWODWORDINTREE(0x66600000,0x00000000)}},
+        {VT_exponent,22,0x3a917e,{DOUBLEWITHTWODWORDINTREE(0x66700000,0x00000000)}},
+        {VT_exponent,22,0x3a917f,{DOUBLEWITHTWODWORDINTREE(0x66800000,0x00000000)}},
+        {VT_exponent,22,0x3a9180,{DOUBLEWITHTWODWORDINTREE(0x66900000,0x00000000)}},
+        {VT_exponent,22,0x3a9181,{DOUBLEWITHTWODWORDINTREE(0x66a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9182,{DOUBLEWITHTWODWORDINTREE(0x66b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9183,{DOUBLEWITHTWODWORDINTREE(0x66c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9184,{DOUBLEWITHTWODWORDINTREE(0x66d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9185,{DOUBLEWITHTWODWORDINTREE(0x66e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9186,{DOUBLEWITHTWODWORDINTREE(0x66f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9187,{DOUBLEWITHTWODWORDINTREE(0x67000000,0x00000000)}},
+        {VT_exponent,22,0x3a9188,{DOUBLEWITHTWODWORDINTREE(0x67100000,0x00000000)}},
+        {VT_exponent,22,0x3a9189,{DOUBLEWITHTWODWORDINTREE(0x67200000,0x00000000)}},
+        {VT_exponent,22,0x3a918a,{DOUBLEWITHTWODWORDINTREE(0x67300000,0x00000000)}},
+        {VT_exponent,22,0x3a918b,{DOUBLEWITHTWODWORDINTREE(0x67400000,0x00000000)}},
+        {VT_exponent,22,0x3a918c,{DOUBLEWITHTWODWORDINTREE(0x67500000,0x00000000)}},
+        {VT_exponent,22,0x3a918d,{DOUBLEWITHTWODWORDINTREE(0x67600000,0x00000000)}},
+        {VT_exponent,22,0x3a918e,{DOUBLEWITHTWODWORDINTREE(0x67700000,0x00000000)}},
+        {VT_exponent,22,0x3a918f,{DOUBLEWITHTWODWORDINTREE(0x67800000,0x00000000)}},
+        {VT_exponent,22,0x3a9190,{DOUBLEWITHTWODWORDINTREE(0x67900000,0x00000000)}},
+        {VT_exponent,22,0x3a9191,{DOUBLEWITHTWODWORDINTREE(0x67a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9192,{DOUBLEWITHTWODWORDINTREE(0x67b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9193,{DOUBLEWITHTWODWORDINTREE(0x67c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9194,{DOUBLEWITHTWODWORDINTREE(0x67d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9195,{DOUBLEWITHTWODWORDINTREE(0x67e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9196,{DOUBLEWITHTWODWORDINTREE(0x67f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9197,{DOUBLEWITHTWODWORDINTREE(0x68000000,0x00000000)}},
+        {VT_exponent,22,0x3a9198,{DOUBLEWITHTWODWORDINTREE(0x68100000,0x00000000)}},
+        {VT_exponent,22,0x3a9199,{DOUBLEWITHTWODWORDINTREE(0x68200000,0x00000000)}},
+        {VT_exponent,22,0x3a919a,{DOUBLEWITHTWODWORDINTREE(0x68300000,0x00000000)}},
+        {VT_exponent,22,0x3a919b,{DOUBLEWITHTWODWORDINTREE(0x68400000,0x00000000)}},
+        {VT_exponent,22,0x3a919c,{DOUBLEWITHTWODWORDINTREE(0x68500000,0x00000000)}},
+        {VT_exponent,22,0x3a919d,{DOUBLEWITHTWODWORDINTREE(0x68600000,0x00000000)}},
+        {VT_exponent,22,0x3a919e,{DOUBLEWITHTWODWORDINTREE(0x68700000,0x00000000)}},
+        {VT_exponent,22,0x3a919f,{DOUBLEWITHTWODWORDINTREE(0x68800000,0x00000000)}},
+        {VT_exponent,22,0x3a91a0,{DOUBLEWITHTWODWORDINTREE(0x68900000,0x00000000)}},
+        {VT_exponent,22,0x3a91a1,{DOUBLEWITHTWODWORDINTREE(0x68a00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a2,{DOUBLEWITHTWODWORDINTREE(0x68b00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a3,{DOUBLEWITHTWODWORDINTREE(0x68c00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a4,{DOUBLEWITHTWODWORDINTREE(0x68d00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a5,{DOUBLEWITHTWODWORDINTREE(0x68e00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a6,{DOUBLEWITHTWODWORDINTREE(0x68f00000,0x00000000)}},
+        {VT_exponent,22,0x3a91a7,{DOUBLEWITHTWODWORDINTREE(0x69000000,0x00000000)}},
+        {VT_exponent,22,0x3a91a8,{DOUBLEWITHTWODWORDINTREE(0x69100000,0x00000000)}},
+        {VT_exponent,22,0x3a91a9,{DOUBLEWITHTWODWORDINTREE(0x69200000,0x00000000)}},
+        {VT_exponent,22,0x3a91aa,{DOUBLEWITHTWODWORDINTREE(0x69300000,0x00000000)}},
+        {VT_exponent,22,0x3a91ab,{DOUBLEWITHTWODWORDINTREE(0x69400000,0x00000000)}},
+        {VT_exponent,22,0x3a91ac,{DOUBLEWITHTWODWORDINTREE(0x69500000,0x00000000)}},
+        {VT_exponent,22,0x3a91ad,{DOUBLEWITHTWODWORDINTREE(0x69600000,0x00000000)}},
+        {VT_exponent,22,0x3a91ae,{DOUBLEWITHTWODWORDINTREE(0x69700000,0x00000000)}},
+        {VT_exponent,22,0x3a91af,{DOUBLEWITHTWODWORDINTREE(0x69800000,0x00000000)}},
+        {VT_exponent,22,0x3a91b0,{DOUBLEWITHTWODWORDINTREE(0x69900000,0x00000000)}},
+        {VT_exponent,22,0x3a91b1,{DOUBLEWITHTWODWORDINTREE(0x69a00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b2,{DOUBLEWITHTWODWORDINTREE(0x69b00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b3,{DOUBLEWITHTWODWORDINTREE(0x69c00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b4,{DOUBLEWITHTWODWORDINTREE(0x69d00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b5,{DOUBLEWITHTWODWORDINTREE(0x69e00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b6,{DOUBLEWITHTWODWORDINTREE(0x69f00000,0x00000000)}},
+        {VT_exponent,22,0x3a91b7,{DOUBLEWITHTWODWORDINTREE(0x6a000000,0x00000000)}},
+        {VT_exponent,22,0x3a91b8,{DOUBLEWITHTWODWORDINTREE(0x6a100000,0x00000000)}},
+        {VT_exponent,22,0x3a91b9,{DOUBLEWITHTWODWORDINTREE(0x6a200000,0x00000000)}},
+        {VT_exponent,22,0x3a91ba,{DOUBLEWITHTWODWORDINTREE(0x6a300000,0x00000000)}},
+        {VT_exponent,22,0x3a91bb,{DOUBLEWITHTWODWORDINTREE(0x6a400000,0x00000000)}},
+        {VT_exponent,22,0x3a91bc,{DOUBLEWITHTWODWORDINTREE(0x6a500000,0x00000000)}},
+        {VT_exponent,22,0x3a91bd,{DOUBLEWITHTWODWORDINTREE(0x6a600000,0x00000000)}},
+        {VT_exponent,22,0x3a91be,{DOUBLEWITHTWODWORDINTREE(0x6a700000,0x00000000)}},
+        {VT_exponent,22,0x3a91bf,{DOUBLEWITHTWODWORDINTREE(0x6a800000,0x00000000)}},
+        {VT_exponent,22,0x3a91c0,{DOUBLEWITHTWODWORDINTREE(0x6a900000,0x00000000)}},
+        {VT_exponent,22,0x3a91c1,{DOUBLEWITHTWODWORDINTREE(0x6aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c2,{DOUBLEWITHTWODWORDINTREE(0x6ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c3,{DOUBLEWITHTWODWORDINTREE(0x6ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c4,{DOUBLEWITHTWODWORDINTREE(0x6ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c5,{DOUBLEWITHTWODWORDINTREE(0x6ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c6,{DOUBLEWITHTWODWORDINTREE(0x6af00000,0x00000000)}},
+        {VT_exponent,22,0x3a91c7,{DOUBLEWITHTWODWORDINTREE(0x6b000000,0x00000000)}},
+        {VT_exponent,22,0x3a91c8,{DOUBLEWITHTWODWORDINTREE(0x6b100000,0x00000000)}},
+        {VT_exponent,22,0x3a91c9,{DOUBLEWITHTWODWORDINTREE(0x6b200000,0x00000000)}},
+        {VT_exponent,22,0x3a91ca,{DOUBLEWITHTWODWORDINTREE(0x6b300000,0x00000000)}},
+        {VT_exponent,22,0x3a91cb,{DOUBLEWITHTWODWORDINTREE(0x6b400000,0x00000000)}},
+        {VT_exponent,22,0x3a91cc,{DOUBLEWITHTWODWORDINTREE(0x6b500000,0x00000000)}},
+        {VT_exponent,22,0x3a91cd,{DOUBLEWITHTWODWORDINTREE(0x6b600000,0x00000000)}},
+        {VT_exponent,22,0x3a91ce,{DOUBLEWITHTWODWORDINTREE(0x6b700000,0x00000000)}},
+        {VT_exponent,22,0x3a91cf,{DOUBLEWITHTWODWORDINTREE(0x6b800000,0x00000000)}},
+        {VT_exponent,22,0x3a91d0,{DOUBLEWITHTWODWORDINTREE(0x6b900000,0x00000000)}},
+        {VT_exponent,22,0x3a91d1,{DOUBLEWITHTWODWORDINTREE(0x6ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d2,{DOUBLEWITHTWODWORDINTREE(0x6bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d3,{DOUBLEWITHTWODWORDINTREE(0x6bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d4,{DOUBLEWITHTWODWORDINTREE(0x6bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d5,{DOUBLEWITHTWODWORDINTREE(0x6be00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d6,{DOUBLEWITHTWODWORDINTREE(0x6bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a91d7,{DOUBLEWITHTWODWORDINTREE(0x6c000000,0x00000000)}},
+        {VT_exponent,22,0x3a91d8,{DOUBLEWITHTWODWORDINTREE(0x6c100000,0x00000000)}},
+        {VT_exponent,22,0x3a91d9,{DOUBLEWITHTWODWORDINTREE(0x6c200000,0x00000000)}},
+        {VT_exponent,22,0x3a91da,{DOUBLEWITHTWODWORDINTREE(0x6c300000,0x00000000)}},
+        {VT_exponent,22,0x3a91db,{DOUBLEWITHTWODWORDINTREE(0x6c400000,0x00000000)}},
+        {VT_exponent,22,0x3a91dc,{DOUBLEWITHTWODWORDINTREE(0x6c500000,0x00000000)}},
+        {VT_exponent,22,0x3a91dd,{DOUBLEWITHTWODWORDINTREE(0x6c600000,0x00000000)}},
+        {VT_exponent,22,0x3a91de,{DOUBLEWITHTWODWORDINTREE(0x6c700000,0x00000000)}},
+        {VT_exponent,22,0x3a91df,{DOUBLEWITHTWODWORDINTREE(0x6c800000,0x00000000)}},
+        {VT_exponent,22,0x3a91e0,{DOUBLEWITHTWODWORDINTREE(0x6c900000,0x00000000)}},
+        {VT_exponent,22,0x3a91e1,{DOUBLEWITHTWODWORDINTREE(0x6ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e2,{DOUBLEWITHTWODWORDINTREE(0x6cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e3,{DOUBLEWITHTWODWORDINTREE(0x6cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e4,{DOUBLEWITHTWODWORDINTREE(0x6cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e5,{DOUBLEWITHTWODWORDINTREE(0x6ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e6,{DOUBLEWITHTWODWORDINTREE(0x6cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a91e7,{DOUBLEWITHTWODWORDINTREE(0x6d000000,0x00000000)}},
+        {VT_exponent,22,0x3a91e8,{DOUBLEWITHTWODWORDINTREE(0x6d100000,0x00000000)}},
+        {VT_exponent,22,0x3a91e9,{DOUBLEWITHTWODWORDINTREE(0x6d200000,0x00000000)}},
+        {VT_exponent,22,0x3a91ea,{DOUBLEWITHTWODWORDINTREE(0x6d300000,0x00000000)}},
+        {VT_exponent,22,0x3a91eb,{DOUBLEWITHTWODWORDINTREE(0x6d400000,0x00000000)}},
+        {VT_exponent,22,0x3a91ec,{DOUBLEWITHTWODWORDINTREE(0x6d500000,0x00000000)}},
+        {VT_exponent,22,0x3a91ed,{DOUBLEWITHTWODWORDINTREE(0x6d600000,0x00000000)}},
+        {VT_exponent,22,0x3a91ee,{DOUBLEWITHTWODWORDINTREE(0x6d700000,0x00000000)}},
+        {VT_exponent,22,0x3a91ef,{DOUBLEWITHTWODWORDINTREE(0x6d800000,0x00000000)}},
+        {VT_exponent,22,0x3a91f0,{DOUBLEWITHTWODWORDINTREE(0x6d900000,0x00000000)}},
+        {VT_exponent,22,0x3a91f1,{DOUBLEWITHTWODWORDINTREE(0x6da00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f2,{DOUBLEWITHTWODWORDINTREE(0x6db00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f3,{DOUBLEWITHTWODWORDINTREE(0x6dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f4,{DOUBLEWITHTWODWORDINTREE(0x6dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f5,{DOUBLEWITHTWODWORDINTREE(0x6de00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f6,{DOUBLEWITHTWODWORDINTREE(0x6df00000,0x00000000)}},
+        {VT_exponent,22,0x3a91f7,{DOUBLEWITHTWODWORDINTREE(0x6e000000,0x00000000)}},
+        {VT_exponent,22,0x3a91f8,{DOUBLEWITHTWODWORDINTREE(0x6e100000,0x00000000)}},
+        {VT_exponent,22,0x3a91f9,{DOUBLEWITHTWODWORDINTREE(0x6e200000,0x00000000)}},
+        {VT_exponent,22,0x3a91fa,{DOUBLEWITHTWODWORDINTREE(0x6e300000,0x00000000)}},
+        {VT_exponent,22,0x3a91fb,{DOUBLEWITHTWODWORDINTREE(0x6e400000,0x00000000)}},
+        {VT_exponent,22,0x3a91fc,{DOUBLEWITHTWODWORDINTREE(0x6e500000,0x00000000)}},
+        {VT_exponent,22,0x3a91fd,{DOUBLEWITHTWODWORDINTREE(0x6e600000,0x00000000)}},
+        {VT_exponent,22,0x3a91fe,{DOUBLEWITHTWODWORDINTREE(0x6e700000,0x00000000)}},
+        {VT_exponent,22,0x3a91ff,{DOUBLEWITHTWODWORDINTREE(0x6e800000,0x00000000)}},
+        {VT_exponent,22,0x3a9200,{DOUBLEWITHTWODWORDINTREE(0x6e900000,0x00000000)}},
+        {VT_exponent,22,0x3a9201,{DOUBLEWITHTWODWORDINTREE(0x6ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a9202,{DOUBLEWITHTWODWORDINTREE(0x6eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9203,{DOUBLEWITHTWODWORDINTREE(0x6ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a9204,{DOUBLEWITHTWODWORDINTREE(0x6ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a9205,{DOUBLEWITHTWODWORDINTREE(0x6ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a9206,{DOUBLEWITHTWODWORDINTREE(0x6ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a9207,{DOUBLEWITHTWODWORDINTREE(0x6f000000,0x00000000)}},
+        {VT_exponent,22,0x3a9208,{DOUBLEWITHTWODWORDINTREE(0x6f100000,0x00000000)}},
+        {VT_exponent,22,0x3a9209,{DOUBLEWITHTWODWORDINTREE(0x6f200000,0x00000000)}},
+        {VT_exponent,22,0x3a920a,{DOUBLEWITHTWODWORDINTREE(0x6f300000,0x00000000)}},
+        {VT_exponent,22,0x3a920b,{DOUBLEWITHTWODWORDINTREE(0x6f400000,0x00000000)}},
+        {VT_exponent,22,0x3a920c,{DOUBLEWITHTWODWORDINTREE(0x6f500000,0x00000000)}},
+        {VT_exponent,22,0x3a920d,{DOUBLEWITHTWODWORDINTREE(0x6f600000,0x00000000)}},
+        {VT_exponent,22,0x3a920e,{DOUBLEWITHTWODWORDINTREE(0x6f700000,0x00000000)}},
+        {VT_exponent,22,0x3a920f,{DOUBLEWITHTWODWORDINTREE(0x6f800000,0x00000000)}},
+        {VT_exponent,22,0x3a9210,{DOUBLEWITHTWODWORDINTREE(0x6f900000,0x00000000)}},
+        {VT_exponent,22,0x3a9211,{DOUBLEWITHTWODWORDINTREE(0x6fa00000,0x00000000)}},
+        {VT_exponent,22,0x3a9212,{DOUBLEWITHTWODWORDINTREE(0x6fb00000,0x00000000)}},
+        {VT_exponent,22,0x3a9213,{DOUBLEWITHTWODWORDINTREE(0x6fc00000,0x00000000)}},
+        {VT_exponent,22,0x3a9214,{DOUBLEWITHTWODWORDINTREE(0x6fd00000,0x00000000)}},
+        {VT_exponent,22,0x3a9215,{DOUBLEWITHTWODWORDINTREE(0x6fe00000,0x00000000)}},
+        {VT_exponent,22,0x3a9216,{DOUBLEWITHTWODWORDINTREE(0x6ff00000,0x00000000)}},
+        {VT_exponent,22,0x3a9217,{DOUBLEWITHTWODWORDINTREE(0x70000000,0x00000000)}},
+        {VT_exponent,22,0x3a9218,{DOUBLEWITHTWODWORDINTREE(0x70100000,0x00000000)}},
+        {VT_exponent,22,0x3a9219,{DOUBLEWITHTWODWORDINTREE(0x70200000,0x00000000)}},
+        {VT_exponent,22,0x3a921a,{DOUBLEWITHTWODWORDINTREE(0x70300000,0x00000000)}},
+        {VT_exponent,22,0x3a921b,{DOUBLEWITHTWODWORDINTREE(0x70400000,0x00000000)}},
+        {VT_exponent,22,0x3a921c,{DOUBLEWITHTWODWORDINTREE(0x70500000,0x00000000)}},
+        {VT_exponent,22,0x3a921d,{DOUBLEWITHTWODWORDINTREE(0x70600000,0x00000000)}},
+        {VT_exponent,22,0x3a921e,{DOUBLEWITHTWODWORDINTREE(0x70700000,0x00000000)}},
+        {VT_exponent,22,0x3a921f,{DOUBLEWITHTWODWORDINTREE(0x70800000,0x00000000)}},
+        {VT_exponent,22,0x3a9220,{DOUBLEWITHTWODWORDINTREE(0x70900000,0x00000000)}},
+        {VT_exponent,22,0x3a9221,{DOUBLEWITHTWODWORDINTREE(0x70a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9222,{DOUBLEWITHTWODWORDINTREE(0x70b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9223,{DOUBLEWITHTWODWORDINTREE(0x70c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9224,{DOUBLEWITHTWODWORDINTREE(0x70d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9225,{DOUBLEWITHTWODWORDINTREE(0x70e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9226,{DOUBLEWITHTWODWORDINTREE(0x70f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9227,{DOUBLEWITHTWODWORDINTREE(0x71000000,0x00000000)}},
+        {VT_exponent,22,0x3a9228,{DOUBLEWITHTWODWORDINTREE(0x71100000,0x00000000)}},
+        {VT_exponent,22,0x3a9229,{DOUBLEWITHTWODWORDINTREE(0x71200000,0x00000000)}},
+        {VT_exponent,22,0x3a922a,{DOUBLEWITHTWODWORDINTREE(0x71300000,0x00000000)}},
+        {VT_exponent,22,0x3a922b,{DOUBLEWITHTWODWORDINTREE(0x71400000,0x00000000)}},
+        {VT_exponent,22,0x3a922c,{DOUBLEWITHTWODWORDINTREE(0x71500000,0x00000000)}},
+        {VT_exponent,22,0x3a922d,{DOUBLEWITHTWODWORDINTREE(0x71600000,0x00000000)}},
+        {VT_exponent,22,0x3a922e,{DOUBLEWITHTWODWORDINTREE(0x71700000,0x00000000)}},
+        {VT_exponent,22,0x3a922f,{DOUBLEWITHTWODWORDINTREE(0x71800000,0x00000000)}},
+        {VT_exponent,22,0x3a9230,{DOUBLEWITHTWODWORDINTREE(0x71900000,0x00000000)}},
+        {VT_exponent,22,0x3a9231,{DOUBLEWITHTWODWORDINTREE(0x71a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9232,{DOUBLEWITHTWODWORDINTREE(0x71b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9233,{DOUBLEWITHTWODWORDINTREE(0x71c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9234,{DOUBLEWITHTWODWORDINTREE(0x71d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9235,{DOUBLEWITHTWODWORDINTREE(0x71e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9236,{DOUBLEWITHTWODWORDINTREE(0x71f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9237,{DOUBLEWITHTWODWORDINTREE(0x72000000,0x00000000)}},
+        {VT_exponent,22,0x3a9238,{DOUBLEWITHTWODWORDINTREE(0x72100000,0x00000000)}},
+        {VT_exponent,22,0x3a9239,{DOUBLEWITHTWODWORDINTREE(0x72200000,0x00000000)}},
+        {VT_exponent,22,0x3a923a,{DOUBLEWITHTWODWORDINTREE(0x72300000,0x00000000)}},
+        {VT_exponent,22,0x3a923b,{DOUBLEWITHTWODWORDINTREE(0x72400000,0x00000000)}},
+        {VT_exponent,22,0x3a923c,{DOUBLEWITHTWODWORDINTREE(0x72500000,0x00000000)}},
+        {VT_exponent,22,0x3a923d,{DOUBLEWITHTWODWORDINTREE(0x72600000,0x00000000)}},
+        {VT_exponent,22,0x3a923e,{DOUBLEWITHTWODWORDINTREE(0x72700000,0x00000000)}},
+        {VT_exponent,22,0x3a923f,{DOUBLEWITHTWODWORDINTREE(0x72800000,0x00000000)}},
+        {VT_exponent,22,0x3a9240,{DOUBLEWITHTWODWORDINTREE(0x72900000,0x00000000)}},
+        {VT_exponent,22,0x3a9241,{DOUBLEWITHTWODWORDINTREE(0x72a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9242,{DOUBLEWITHTWODWORDINTREE(0x72b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9243,{DOUBLEWITHTWODWORDINTREE(0x72c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9244,{DOUBLEWITHTWODWORDINTREE(0x72d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9245,{DOUBLEWITHTWODWORDINTREE(0x72e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9246,{DOUBLEWITHTWODWORDINTREE(0x72f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9247,{DOUBLEWITHTWODWORDINTREE(0x73000000,0x00000000)}},
+        {VT_exponent,22,0x3a9248,{DOUBLEWITHTWODWORDINTREE(0x73100000,0x00000000)}},
+        {VT_exponent,22,0x3a9249,{DOUBLEWITHTWODWORDINTREE(0x73200000,0x00000000)}},
+        {VT_exponent,22,0x3a924a,{DOUBLEWITHTWODWORDINTREE(0x73300000,0x00000000)}},
+        {VT_exponent,22,0x3a924b,{DOUBLEWITHTWODWORDINTREE(0x73400000,0x00000000)}},
+        {VT_exponent,22,0x3a924c,{DOUBLEWITHTWODWORDINTREE(0x73500000,0x00000000)}},
+        {VT_exponent,22,0x3a924d,{DOUBLEWITHTWODWORDINTREE(0x73600000,0x00000000)}},
+        {VT_exponent,22,0x3a924e,{DOUBLEWITHTWODWORDINTREE(0x73700000,0x00000000)}},
+        {VT_exponent,22,0x3a924f,{DOUBLEWITHTWODWORDINTREE(0x73800000,0x00000000)}},
+        {VT_exponent,22,0x3a9250,{DOUBLEWITHTWODWORDINTREE(0x73900000,0x00000000)}},
+        {VT_exponent,22,0x3a9251,{DOUBLEWITHTWODWORDINTREE(0x73a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9252,{DOUBLEWITHTWODWORDINTREE(0x73b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9253,{DOUBLEWITHTWODWORDINTREE(0x73c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9254,{DOUBLEWITHTWODWORDINTREE(0x73d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9255,{DOUBLEWITHTWODWORDINTREE(0x73e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9256,{DOUBLEWITHTWODWORDINTREE(0x73f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9257,{DOUBLEWITHTWODWORDINTREE(0x74000000,0x00000000)}},
+        {VT_exponent,22,0x3a9258,{DOUBLEWITHTWODWORDINTREE(0x74100000,0x00000000)}},
+        {VT_exponent,22,0x3a9259,{DOUBLEWITHTWODWORDINTREE(0x74200000,0x00000000)}},
+        {VT_exponent,22,0x3a925a,{DOUBLEWITHTWODWORDINTREE(0x74300000,0x00000000)}},
+        {VT_exponent,22,0x3a925b,{DOUBLEWITHTWODWORDINTREE(0x74400000,0x00000000)}},
+        {VT_exponent,22,0x3a925c,{DOUBLEWITHTWODWORDINTREE(0x74500000,0x00000000)}},
+        {VT_exponent,22,0x3a925d,{DOUBLEWITHTWODWORDINTREE(0x74600000,0x00000000)}},
+        {VT_exponent,22,0x3a925e,{DOUBLEWITHTWODWORDINTREE(0x74700000,0x00000000)}},
+        {VT_exponent,22,0x3a925f,{DOUBLEWITHTWODWORDINTREE(0x74800000,0x00000000)}},
+        {VT_exponent,22,0x3a9260,{DOUBLEWITHTWODWORDINTREE(0x74900000,0x00000000)}},
+        {VT_exponent,22,0x3a9261,{DOUBLEWITHTWODWORDINTREE(0x74a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9262,{DOUBLEWITHTWODWORDINTREE(0x74b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9263,{DOUBLEWITHTWODWORDINTREE(0x74c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9264,{DOUBLEWITHTWODWORDINTREE(0x74d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9265,{DOUBLEWITHTWODWORDINTREE(0x74e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9266,{DOUBLEWITHTWODWORDINTREE(0x74f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9267,{DOUBLEWITHTWODWORDINTREE(0x75000000,0x00000000)}},
+        {VT_exponent,22,0x3a9268,{DOUBLEWITHTWODWORDINTREE(0x75100000,0x00000000)}},
+        {VT_exponent,22,0x3a9269,{DOUBLEWITHTWODWORDINTREE(0x75200000,0x00000000)}},
+        {VT_exponent,22,0x3a926a,{DOUBLEWITHTWODWORDINTREE(0x75300000,0x00000000)}},
+        {VT_exponent,22,0x3a926b,{DOUBLEWITHTWODWORDINTREE(0x75400000,0x00000000)}},
+        {VT_exponent,22,0x3a926c,{DOUBLEWITHTWODWORDINTREE(0x75500000,0x00000000)}},
+        {VT_exponent,22,0x3a926d,{DOUBLEWITHTWODWORDINTREE(0x75600000,0x00000000)}},
+        {VT_exponent,22,0x3a926e,{DOUBLEWITHTWODWORDINTREE(0x75700000,0x00000000)}},
+        {VT_exponent,22,0x3a926f,{DOUBLEWITHTWODWORDINTREE(0x75800000,0x00000000)}},
+        {VT_exponent,22,0x3a9270,{DOUBLEWITHTWODWORDINTREE(0x75900000,0x00000000)}},
+        {VT_exponent,22,0x3a9271,{DOUBLEWITHTWODWORDINTREE(0x75a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9272,{DOUBLEWITHTWODWORDINTREE(0x75b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9273,{DOUBLEWITHTWODWORDINTREE(0x75c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9274,{DOUBLEWITHTWODWORDINTREE(0x75d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9275,{DOUBLEWITHTWODWORDINTREE(0x75e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9276,{DOUBLEWITHTWODWORDINTREE(0x75f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9277,{DOUBLEWITHTWODWORDINTREE(0x76000000,0x00000000)}},
+        {VT_exponent,22,0x3a9278,{DOUBLEWITHTWODWORDINTREE(0x76100000,0x00000000)}},
+        {VT_exponent,22,0x3a9279,{DOUBLEWITHTWODWORDINTREE(0x76200000,0x00000000)}},
+        {VT_exponent,22,0x3a927a,{DOUBLEWITHTWODWORDINTREE(0x76300000,0x00000000)}},
+        {VT_exponent,22,0x3a927b,{DOUBLEWITHTWODWORDINTREE(0x76400000,0x00000000)}},
+        {VT_exponent,22,0x3a927c,{DOUBLEWITHTWODWORDINTREE(0x76500000,0x00000000)}},
+        {VT_exponent,22,0x3a927d,{DOUBLEWITHTWODWORDINTREE(0x76600000,0x00000000)}},
+        {VT_exponent,22,0x3a927e,{DOUBLEWITHTWODWORDINTREE(0x76700000,0x00000000)}},
+        {VT_exponent,22,0x3a927f,{DOUBLEWITHTWODWORDINTREE(0x76800000,0x00000000)}},
+        {VT_exponent,22,0x3a9280,{DOUBLEWITHTWODWORDINTREE(0x76900000,0x00000000)}},
+        {VT_exponent,22,0x3a9281,{DOUBLEWITHTWODWORDINTREE(0x76a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9282,{DOUBLEWITHTWODWORDINTREE(0x76b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9283,{DOUBLEWITHTWODWORDINTREE(0x76c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9284,{DOUBLEWITHTWODWORDINTREE(0x76d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9285,{DOUBLEWITHTWODWORDINTREE(0x76e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9286,{DOUBLEWITHTWODWORDINTREE(0x76f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9287,{DOUBLEWITHTWODWORDINTREE(0x77000000,0x00000000)}},
+        {VT_exponent,22,0x3a9288,{DOUBLEWITHTWODWORDINTREE(0x77100000,0x00000000)}},
+        {VT_exponent,22,0x3a9289,{DOUBLEWITHTWODWORDINTREE(0x77200000,0x00000000)}},
+        {VT_exponent,22,0x3a928a,{DOUBLEWITHTWODWORDINTREE(0x77300000,0x00000000)}},
+        {VT_exponent,22,0x3a928b,{DOUBLEWITHTWODWORDINTREE(0x77400000,0x00000000)}},
+        {VT_exponent,22,0x3a928c,{DOUBLEWITHTWODWORDINTREE(0x77500000,0x00000000)}},
+        {VT_exponent,22,0x3a928d,{DOUBLEWITHTWODWORDINTREE(0x77600000,0x00000000)}},
+        {VT_exponent,22,0x3a928e,{DOUBLEWITHTWODWORDINTREE(0x77700000,0x00000000)}},
+        {VT_exponent,22,0x3a928f,{DOUBLEWITHTWODWORDINTREE(0x77800000,0x00000000)}},
+        {VT_exponent,22,0x3a9290,{DOUBLEWITHTWODWORDINTREE(0x77900000,0x00000000)}},
+        {VT_exponent,22,0x3a9291,{DOUBLEWITHTWODWORDINTREE(0x77a00000,0x00000000)}},
+        {VT_exponent,22,0x3a9292,{DOUBLEWITHTWODWORDINTREE(0x77b00000,0x00000000)}},
+        {VT_exponent,22,0x3a9293,{DOUBLEWITHTWODWORDINTREE(0x77c00000,0x00000000)}},
+        {VT_exponent,22,0x3a9294,{DOUBLEWITHTWODWORDINTREE(0x77d00000,0x00000000)}},
+        {VT_exponent,22,0x3a9295,{DOUBLEWITHTWODWORDINTREE(0x77e00000,0x00000000)}},
+        {VT_exponent,22,0x3a9296,{DOUBLEWITHTWODWORDINTREE(0x77f00000,0x00000000)}},
+        {VT_exponent,22,0x3a9297,{DOUBLEWITHTWODWORDINTREE(0x78000000,0x00000000)}},
+        {VT_exponent,22,0x3a9298,{DOUBLEWITHTWODWORDINTREE(0x78100000,0x00000000)}},
+        {VT_exponent,22,0x3a9299,{DOUBLEWITHTWODWORDINTREE(0x78200000,0x00000000)}},
+        {VT_exponent,22,0x3a929a,{DOUBLEWITHTWODWORDINTREE(0x78300000,0x00000000)}},
+        {VT_exponent,22,0x3a929b,{DOUBLEWITHTWODWORDINTREE(0x78400000,0x00000000)}},
+        {VT_exponent,22,0x3a929c,{DOUBLEWITHTWODWORDINTREE(0x78500000,0x00000000)}},
+        {VT_exponent,22,0x3a929d,{DOUBLEWITHTWODWORDINTREE(0x78600000,0x00000000)}},
+        {VT_exponent,22,0x3a929e,{DOUBLEWITHTWODWORDINTREE(0x78700000,0x00000000)}},
+        {VT_exponent,22,0x3a929f,{DOUBLEWITHTWODWORDINTREE(0x78800000,0x00000000)}},
+        {VT_exponent,22,0x3a92a0,{DOUBLEWITHTWODWORDINTREE(0x78900000,0x00000000)}},
+        {VT_exponent,22,0x3a92a1,{DOUBLEWITHTWODWORDINTREE(0x78a00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a2,{DOUBLEWITHTWODWORDINTREE(0x78b00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a3,{DOUBLEWITHTWODWORDINTREE(0x78c00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a4,{DOUBLEWITHTWODWORDINTREE(0x78d00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a5,{DOUBLEWITHTWODWORDINTREE(0x78e00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a6,{DOUBLEWITHTWODWORDINTREE(0x78f00000,0x00000000)}},
+        {VT_exponent,22,0x3a92a7,{DOUBLEWITHTWODWORDINTREE(0x79000000,0x00000000)}},
+        {VT_exponent,22,0x3a92a8,{DOUBLEWITHTWODWORDINTREE(0x79100000,0x00000000)}},
+        {VT_exponent,22,0x3a92a9,{DOUBLEWITHTWODWORDINTREE(0x79200000,0x00000000)}},
+        {VT_exponent,22,0x3a92aa,{DOUBLEWITHTWODWORDINTREE(0x79300000,0x00000000)}},
+        {VT_exponent,22,0x3a92ab,{DOUBLEWITHTWODWORDINTREE(0x79400000,0x00000000)}},
+        {VT_exponent,22,0x3a92ac,{DOUBLEWITHTWODWORDINTREE(0x79500000,0x00000000)}},
+        {VT_exponent,22,0x3a92ad,{DOUBLEWITHTWODWORDINTREE(0x79600000,0x00000000)}},
+        {VT_exponent,22,0x3a92ae,{DOUBLEWITHTWODWORDINTREE(0x79700000,0x00000000)}},
+        {VT_exponent,22,0x3a92af,{DOUBLEWITHTWODWORDINTREE(0x79800000,0x00000000)}},
+        {VT_exponent,22,0x3a92b0,{DOUBLEWITHTWODWORDINTREE(0x79900000,0x00000000)}},
+        {VT_exponent,22,0x3a92b1,{DOUBLEWITHTWODWORDINTREE(0x79a00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b2,{DOUBLEWITHTWODWORDINTREE(0x79b00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b3,{DOUBLEWITHTWODWORDINTREE(0x79c00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b4,{DOUBLEWITHTWODWORDINTREE(0x79d00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b5,{DOUBLEWITHTWODWORDINTREE(0x79e00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b6,{DOUBLEWITHTWODWORDINTREE(0x79f00000,0x00000000)}},
+        {VT_exponent,22,0x3a92b7,{DOUBLEWITHTWODWORDINTREE(0x7a000000,0x00000000)}},
+        {VT_exponent,22,0x3a92b8,{DOUBLEWITHTWODWORDINTREE(0x7a100000,0x00000000)}},
+        {VT_exponent,22,0x3a92b9,{DOUBLEWITHTWODWORDINTREE(0x7a200000,0x00000000)}},
+        {VT_exponent,22,0x3a92ba,{DOUBLEWITHTWODWORDINTREE(0x7a300000,0x00000000)}},
+        {VT_exponent,22,0x3a92bb,{DOUBLEWITHTWODWORDINTREE(0x7a400000,0x00000000)}},
+        {VT_exponent,22,0x3a92bc,{DOUBLEWITHTWODWORDINTREE(0x7a500000,0x00000000)}},
+        {VT_exponent,22,0x3a92bd,{DOUBLEWITHTWODWORDINTREE(0x7a600000,0x00000000)}},
+        {VT_exponent,22,0x3a92be,{DOUBLEWITHTWODWORDINTREE(0x7a700000,0x00000000)}},
+        {VT_exponent,22,0x3a92bf,{DOUBLEWITHTWODWORDINTREE(0x7a800000,0x00000000)}},
+        {VT_exponent,22,0x3a92c0,{DOUBLEWITHTWODWORDINTREE(0x7a900000,0x00000000)}},
+        {VT_exponent,22,0x3a92c1,{DOUBLEWITHTWODWORDINTREE(0x7aa00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c2,{DOUBLEWITHTWODWORDINTREE(0x7ab00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c3,{DOUBLEWITHTWODWORDINTREE(0x7ac00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c4,{DOUBLEWITHTWODWORDINTREE(0x7ad00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c5,{DOUBLEWITHTWODWORDINTREE(0x7ae00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c6,{DOUBLEWITHTWODWORDINTREE(0x7af00000,0x00000000)}},
+        {VT_exponent,22,0x3a92c7,{DOUBLEWITHTWODWORDINTREE(0x7b000000,0x00000000)}},
+        {VT_exponent,22,0x3a92c8,{DOUBLEWITHTWODWORDINTREE(0x7b100000,0x00000000)}},
+        {VT_exponent,22,0x3a92c9,{DOUBLEWITHTWODWORDINTREE(0x7b200000,0x00000000)}},
+        {VT_exponent,22,0x3a92ca,{DOUBLEWITHTWODWORDINTREE(0x7b300000,0x00000000)}},
+        {VT_exponent,22,0x3a92cb,{DOUBLEWITHTWODWORDINTREE(0x7b400000,0x00000000)}},
+        {VT_exponent,22,0x3a92cc,{DOUBLEWITHTWODWORDINTREE(0x7b500000,0x00000000)}},
+        {VT_exponent,22,0x3a92cd,{DOUBLEWITHTWODWORDINTREE(0x7b600000,0x00000000)}},
+        {VT_exponent,22,0x3a92ce,{DOUBLEWITHTWODWORDINTREE(0x7b700000,0x00000000)}},
+        {VT_exponent,22,0x3a92cf,{DOUBLEWITHTWODWORDINTREE(0x7b800000,0x00000000)}},
+        {VT_exponent,22,0x3a92d0,{DOUBLEWITHTWODWORDINTREE(0x7b900000,0x00000000)}},
+        {VT_exponent,22,0x3a92d1,{DOUBLEWITHTWODWORDINTREE(0x7ba00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d2,{DOUBLEWITHTWODWORDINTREE(0x7bb00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d3,{DOUBLEWITHTWODWORDINTREE(0x7bc00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d4,{DOUBLEWITHTWODWORDINTREE(0x7bd00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d5,{DOUBLEWITHTWODWORDINTREE(0x7be00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d6,{DOUBLEWITHTWODWORDINTREE(0x7bf00000,0x00000000)}},
+        {VT_exponent,22,0x3a92d7,{DOUBLEWITHTWODWORDINTREE(0x7c000000,0x00000000)}},
+        {VT_exponent,22,0x3a92d8,{DOUBLEWITHTWODWORDINTREE(0x7c100000,0x00000000)}},
+        {VT_exponent,22,0x3a92d9,{DOUBLEWITHTWODWORDINTREE(0x7c200000,0x00000000)}},
+        {VT_exponent,22,0x3a92da,{DOUBLEWITHTWODWORDINTREE(0x7c300000,0x00000000)}},
+        {VT_exponent,22,0x3a92db,{DOUBLEWITHTWODWORDINTREE(0x7c400000,0x00000000)}},
+        {VT_exponent,22,0x3a92dc,{DOUBLEWITHTWODWORDINTREE(0x7c500000,0x00000000)}},
+        {VT_exponent,22,0x3a92dd,{DOUBLEWITHTWODWORDINTREE(0x7c600000,0x00000000)}},
+        {VT_exponent,22,0x3a92de,{DOUBLEWITHTWODWORDINTREE(0x7c700000,0x00000000)}},
+        {VT_exponent,22,0x3a92df,{DOUBLEWITHTWODWORDINTREE(0x7c800000,0x00000000)}},
+        {VT_exponent,22,0x3a92e0,{DOUBLEWITHTWODWORDINTREE(0x7c900000,0x00000000)}},
+        {VT_exponent,22,0x3a92e1,{DOUBLEWITHTWODWORDINTREE(0x7ca00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e2,{DOUBLEWITHTWODWORDINTREE(0x7cb00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e3,{DOUBLEWITHTWODWORDINTREE(0x7cc00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e4,{DOUBLEWITHTWODWORDINTREE(0x7cd00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e5,{DOUBLEWITHTWODWORDINTREE(0x7ce00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e6,{DOUBLEWITHTWODWORDINTREE(0x7cf00000,0x00000000)}},
+        {VT_exponent,22,0x3a92e7,{DOUBLEWITHTWODWORDINTREE(0x7d000000,0x00000000)}},
+        {VT_exponent,22,0x3a92e8,{DOUBLEWITHTWODWORDINTREE(0x7d100000,0x00000000)}},
+        {VT_exponent,22,0x3a92e9,{DOUBLEWITHTWODWORDINTREE(0x7d200000,0x00000000)}},
+        {VT_exponent,22,0x3a92ea,{DOUBLEWITHTWODWORDINTREE(0x7d300000,0x00000000)}},
+        {VT_exponent,22,0x3a92eb,{DOUBLEWITHTWODWORDINTREE(0x7d400000,0x00000000)}},
+        {VT_exponent,22,0x3a92ec,{DOUBLEWITHTWODWORDINTREE(0x7d500000,0x00000000)}},
+        {VT_exponent,22,0x3a92ed,{DOUBLEWITHTWODWORDINTREE(0x7d600000,0x00000000)}},
+        {VT_exponent,22,0x3a92ee,{DOUBLEWITHTWODWORDINTREE(0x7d700000,0x00000000)}},
+        {VT_exponent,22,0x3a92ef,{DOUBLEWITHTWODWORDINTREE(0x7d800000,0x00000000)}},
+        {VT_exponent,22,0x3a92f0,{DOUBLEWITHTWODWORDINTREE(0x7d900000,0x00000000)}},
+        {VT_exponent,22,0x3a92f1,{DOUBLEWITHTWODWORDINTREE(0x7da00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f2,{DOUBLEWITHTWODWORDINTREE(0x7db00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f3,{DOUBLEWITHTWODWORDINTREE(0x7dc00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f4,{DOUBLEWITHTWODWORDINTREE(0x7dd00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f5,{DOUBLEWITHTWODWORDINTREE(0x7de00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f6,{DOUBLEWITHTWODWORDINTREE(0x7df00000,0x00000000)}},
+        {VT_exponent,22,0x3a92f7,{DOUBLEWITHTWODWORDINTREE(0x7e000000,0x00000000)}},
+        {VT_exponent,22,0x3a92f8,{DOUBLEWITHTWODWORDINTREE(0x7e100000,0x00000000)}},
+        {VT_exponent,22,0x3a92f9,{DOUBLEWITHTWODWORDINTREE(0x7e200000,0x00000000)}},
+        {VT_exponent,22,0x3a92fa,{DOUBLEWITHTWODWORDINTREE(0x7e300000,0x00000000)}},
+        {VT_exponent,22,0x3a92fb,{DOUBLEWITHTWODWORDINTREE(0x7e400000,0x00000000)}},
+        {VT_exponent,22,0x3a92fc,{DOUBLEWITHTWODWORDINTREE(0x7e500000,0x00000000)}},
+        {VT_exponent,22,0x3a92fd,{DOUBLEWITHTWODWORDINTREE(0x7e600000,0x00000000)}},
+        {VT_exponent,22,0x3a92fe,{DOUBLEWITHTWODWORDINTREE(0x7e700000,0x00000000)}},
+        {VT_exponent,22,0x3a92ff,{DOUBLEWITHTWODWORDINTREE(0x7e800000,0x00000000)}},
+        {VT_exponent,22,0x3a95a0,{DOUBLEWITHTWODWORDINTREE(0x7e900000,0x00000000)}},
+        {VT_exponent,22,0x3a95a1,{DOUBLEWITHTWODWORDINTREE(0x7ea00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a2,{DOUBLEWITHTWODWORDINTREE(0x7eb00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a3,{DOUBLEWITHTWODWORDINTREE(0x7ec00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a4,{DOUBLEWITHTWODWORDINTREE(0x7ed00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a5,{DOUBLEWITHTWODWORDINTREE(0x7ee00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a6,{DOUBLEWITHTWODWORDINTREE(0x7ef00000,0x00000000)}},
+        {VT_exponent,22,0x3a95a7,{DOUBLEWITHTWODWORDINTREE(0x7f000000,0x00000000)}},
+        {VT_exponent,22,0x3a95a8,{DOUBLEWITHTWODWORDINTREE(0x7f100000,0x00000000)}},
+        {VT_exponent,22,0x3a95a9,{DOUBLEWITHTWODWORDINTREE(0x7f200000,0x00000000)}},
+        {VT_exponent,22,0x3a95aa,{DOUBLEWITHTWODWORDINTREE(0x7f300000,0x00000000)}},
+        {VT_exponent,22,0x3a95ab,{DOUBLEWITHTWODWORDINTREE(0x7f400000,0x00000000)}},
+        {VT_exponent,22,0x3a95ac,{DOUBLEWITHTWODWORDINTREE(0x7f500000,0x00000000)}},
+        {VT_exponent,22,0x3a95ad,{DOUBLEWITHTWODWORDINTREE(0x7f600000,0x00000000)}},
+        {VT_exponent,22,0x3a95ae,{DOUBLEWITHTWODWORDINTREE(0x7f700000,0x00000000)}},
+        {VT_exponent,22,0x3a95af,{DOUBLEWITHTWODWORDINTREE(0x7f800000,0x00000000)}},
+        {VT_exponent,22,0x3b8fe0,{DOUBLEWITHTWODWORDINTREE(0x7f900000,0x00000000)}},
+        {VT_exponent,22,0x3b8fe1,{DOUBLEWITHTWODWORDINTREE(0x7fa00000,0x00000000)}},
+        {VT_exponent,22,0x3b8fe2,{DOUBLEWITHTWODWORDINTREE(0x7fb00000,0x00000000)}},
+        {VT_exponent,22,0x3b8fe3,{DOUBLEWITHTWODWORDINTREE(0x7fc00000,0x00000000)}},
+        {VT_exponent,21,0x68e90,{DOUBLEWITHTWODWORDINTREE(0x7fd00000,0x00000000)}},
+        {VT_exponent,21,0x68e91,{DOUBLEWITHTWODWORDINTREE(0x7fe00000,0x00000000)}},
+        {VT_exponent,21,0x68e98,{DOUBLEWITHTWODWORDINTREE(0x7ff80000,0x00000000)}},
+}; // End of acofdoe array
diff --git a/src/prc/PRCdouble.h b/src/prc/PRCdouble.h
new file mode 100644 (file)
index 0000000..4a3a79d
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef __PRC_DOUBLE_H
+#define __PRC_DOUBLE_H
+
+#include <cstdlib>
+#include <cmath>
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef BYTE_ORDER
+# undef WORDS_BIG_ENDIAN
+# undef WORDS_LITTLE_ENDIAN
+# if BYTE_ORDER == BIG_ENDIAN
+#  define WORDS_BIG_ENDIAN 1
+# endif
+# if BYTE_ORDER == LITTLE_ENDIAN
+#  define WORDS_LITTLE_ENDIAN 1
+# endif
+#endif   
+
+// from Adobe's documentation
+
+union ieee754_double
+{
+ double d;
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#ifdef WORDS_BIGENDIAN
+  unsigned int negative:1;
+  unsigned int exponent:11;
+  /* Together these comprise the mantissa.  */
+  unsigned int mantissa0:20;
+  unsigned int mantissa1:32;
+#else
+  /* Together these comprise the mantissa.  */
+  unsigned int mantissa1:32;
+  unsigned int mantissa0:20;
+  unsigned int exponent:11;
+  unsigned int negative:1;
+#endif
+ } ieee;
+};
+
+union ieee754_float
+{
+ float f;
+ /* This is the IEEE 754 float-precision format. */
+ struct {
+#ifdef WORDS_BIGENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#else
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif
+ } ieee;
+};
+
+enum ValueType {VT_double,VT_exponent};
+
+struct sCodageOfFrequentDoubleOrExponent
+{
+  short Type;
+  short NumberOfBits;
+  unsigned Bits;
+  union {
+    unsigned ul[2];
+    double Value;
+  } u2uod;
+};
+
+#ifdef WORDS_BIGENDIAN
+#       define DOUBLEWITHTWODWORD(upper,lower)  upper,lower
+#       define UPPERPOWER       (0)
+#       define LOWERPOWER       (!UPPERPOWER)
+
+#       define NEXTBYTE(pbd)                            ((pbd)++)
+#       define PREVIOUSBYTE(pbd)                ((pbd)--)
+#       define MOREBYTE(pbd,pbend)              ((pbd)<=(pbend))
+#       define OFFSETBYTE(pbd,offset)   ((pbd)+=offset)
+#       define BEFOREBYTE(pbd)                  ((pbd)-1)
+#       define DIFFPOINTERS(p1,p2)              ((p1)-(p2))
+#       define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memrchr((pbstart),(b),(nb))
+#       define BYTEAT(pb,i)     *((pb)-(i))
+#else
+#       define DOUBLEWITHTWODWORD(upper,lower)  lower,upper
+#       define UPPERPOWER       (1)
+#       define LOWERPOWER       (!UPPERPOWER)
+
+#       define NEXTBYTE(pbd)                            ((pbd)--)
+#       define PREVIOUSBYTE(pbd)                ((pbd)++)
+#       define MOREBYTE(pbd,pbend)              ((pbd)>=(pbend))
+#       define OFFSETBYTE(pbd,offset)   ((pbd)-=offset)
+#       define BEFOREBYTE(pbd)                  ((pbd)+1)
+#       define DIFFPOINTERS(p1,p2)              ((unsigned)((p2)-(p1)))
+#       define SEARCHBYTE(pbstart,b,nb) (unsigned char *)memchr((pbstart),(b),(nb))
+#       define BYTEAT(pb,i)     *((pb)+(i))
+#endif
+
+#define MAXLENGTHFORCOMPRESSEDTYPE      ((22+1+1+4+6*(1+8))+7)/8
+
+#define NEGATIVE(d)     (((union ieee754_double *)&(d))->ieee.negative)
+#define EXPONENT(d)     (((union ieee754_double *)&(d))->ieee.exponent)
+#define MANTISSA0(d)    (((union ieee754_double *)&(d))->ieee.mantissa0)
+#define MANTISSA1(d)    (((union ieee754_double *)&(d))->ieee.mantissa1)
+
+typedef unsigned char PRCbyte;
+typedef unsigned short PRCword;
+typedef unsigned PRCdword;
+
+extern PRCdword stadwZero[2],stadwNegativeZero[2];
+
+#define NUMBEROFELEMENTINACOFDOE   (2077)
+
+#ifdef WORDS_BIGENDIAN
+#       define DOUBLEWITHTWODWORDINTREE(upper,lower)    {upper,lower} 
+#else
+#       define DOUBLEWITHTWODWORDINTREE(upper,lower)    {lower,upper}
+#endif
+extern sCodageOfFrequentDoubleOrExponent acofdoe[NUMBEROFELEMENTINACOFDOE];
+
+struct sCodageOfFrequentDoubleOrExponent* getcofdoe(unsigned,short);
+
+#define STAT_V
+#define STAT_DOUBLE
+
+int stCOFDOECompare(const void*,const void*);
+
+#ifdef WORDS_BIGENDIAN
+#ifndef HAVE_MEMRCHR
+void *memrchr(const void *,int,size_t);
+#endif
+#endif
+
+#endif // __PRC_DOUBLE_H
diff --git a/src/prc/oPRCFile.cc b/src/prc/oPRCFile.cc
new file mode 100644 (file)
index 0000000..d300aae
--- /dev/null
@@ -0,0 +1,2353 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*   with enhancements contributed by Michail Vidiassov.
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "oPRCFile.h"
+#include <time.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <string>
+#include <zlib.h>
+#include <string.h>
+
+#define WriteUnsignedInteger( value ) out << (uint32_t)(value);
+#define WriteInteger( value ) out << (int32_t)(value);
+#define WriteDouble( value ) out << (double)(value);
+#define WriteString( value ) out << (value);
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define WriteUncompressedBlock( value, count ) out.write((char *)(value),(count));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+#define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(out);
+#define SerializeContentPRCBase write(out);
+#define SerializeRgbColor( value ) (value).serializeRgbColor(out);
+#define SerializePicture( value ) (value).serializePicture(out);
+#define SerializeTextureDefinition( value ) (value)->serializeTextureDefinition(out);
+#define SerializeMarkup( value ) (value)->serializeMarkup(out);
+#define SerializeAnnotationEntity( value ) (value)->serializeAnnotationEntity(out);
+#define SerializeFontKeysSameFont( value ) (value).serializeFontKeysSameFont(out);
+#define SerializeMaterial( value ) (value)->serializeMaterial(out);
+
+#define SerializeUserData UserData(0,0).write(out);
+#define SerializeEmptyContentPRCBase ContentPRCBase(PRC_TYPE_ROOT_PRCBase).serializeContentPRCBase(out);
+#define SerializeCategory1LineStyle( value ) (value)->serializeCategory1LineStyle(out);
+#define SerializeCoordinateSystem( value ) (value)->serializeCoordinateSystem(out);
+#define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(out);
+#define SerializePartDefinition( value ) (value)->serializePartDefinition(out);
+#define SerializeProductOccurrence( value ) (value)->serializeProductOccurrence(out);
+#define SerializeContextAndBodies( value ) (value)->serializeContextAndBodies(out);
+#define SerializeGeometrySummary( value ) (value)->serializeGeometrySummary(out);
+#define SerializeContextGraphics( value ) (value)->serializeContextGraphics(out);
+#define SerializeStartHeader serializeStartHeader(out);
+#define SerializeUncompressedFiles  \
+ { \
+  const uint32_t number_of_uncompressed_files = uncompressed_files.size(); \
+  WriteUncompressedUnsignedInteger (number_of_uncompressed_files) \
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++) \
+  { \
+    WriteUncompressedUnsignedInteger ((*it)->file_size) \
+    WriteUncompressedBlock ((*it)->data, (*it)->file_size) \
+  } \
+ }
+#define SerializeModelFileData serializeModelFileData(modelFile_out); modelFile_out.compress();
+#define SerializeUnit( value ) (value).serializeUnit(out);
+
+using std::string;
+using namespace std;
+
+// Map [0,1] to [0,255]
+inline uint8_t byte(double r) 
+{
+  if(r < 0.0) r=0.0;
+  else if(r > 1.0) r=1.0;
+  int a=(int)(256.0*r);
+  if(a == 256) a=255;
+  return a;
+}
+
+void PRCFileStructure::serializeFileStructureGlobals(PRCbitStream &out)
+{
+  // even though this is technically not part of this section,
+  // it is handled here for convenience
+  const uint32_t number_of_schema = 0;
+  WriteUnsignedInteger (number_of_schema)
+
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGlobals)
+
+  PRCSingleAttribute sa((int32_t)PRCVersion);
+  PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
+  a.addKey(sa);
+  ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase);
+  cb.addAttribute(a);
+  cb.serializeContentPRCBase(out);
+  WriteUnsignedInteger (number_of_referenced_file_structures)
+  // SerializeFileStructureInternalGlobalData
+  WriteDouble (tessellation_chord_height_ratio)
+  WriteDouble (tessellation_angle_degree)
+
+  // SerializeMarkupSerializationHelper
+  WriteString (default_font_family_name)
+
+  const uint32_t number_of_fonts = font_keys_of_font.size();
+  WriteUnsignedInteger (number_of_fonts)
+  for (uint32_t i=0;i<number_of_fonts;i++)
+  {
+    SerializeFontKeysSameFont (font_keys_of_font[i])
+  }
+
+  const uint32_t number_of_colors = colors.size();
+  WriteUnsignedInteger (number_of_colors)
+  for (uint32_t i=0;i<number_of_colors;i++)
+      SerializeRgbColor (colors[i])
+
+  const uint32_t number_of_pictures = pictures.size();
+  WriteUnsignedInteger (number_of_pictures)
+  for (uint32_t i=0;i<number_of_pictures;i++)
+     SerializePicture (pictures[i])
+
+  const uint32_t number_of_texture_definitions = texture_definitions.size();
+  WriteUnsignedInteger (number_of_texture_definitions)
+  for (uint32_t i=0;i<number_of_texture_definitions;i++)
+     SerializeTextureDefinition (texture_definitions[i])
+
+  const uint32_t number_of_materials = materials.size();
+  WriteUnsignedInteger (number_of_materials)
+  for (uint32_t i=0;i<number_of_materials;i++)
+     SerializeMaterial (materials[i])
+
+  // number of line patterns hard coded for now
+  const uint32_t number_of_line_patterns = 1;
+  WriteUnsignedInteger (number_of_line_patterns)
+  PRCLinePattern().serializeLinePattern(out);
+
+  const uint32_t number_of_styles = styles.size();
+  WriteUnsignedInteger (number_of_styles)
+  for (uint32_t i=0;i<number_of_styles;i++)
+     SerializeCategory1LineStyle (styles[i])
+
+  const uint32_t number_of_fill_patterns = 0;
+  WriteUnsignedInteger (number_of_fill_patterns)
+
+  const uint32_t number_of_reference_coordinate_systems = reference_coordinate_systems.size();
+  WriteUnsignedInteger (number_of_reference_coordinate_systems)
+  for (uint32_t i=0;i<number_of_reference_coordinate_systems;i++)
+     SerializeCoordinateSystem (reference_coordinate_systems[i])
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTree(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTree)
+
+  SerializeEmptyContentPRCBase
+
+  const uint32_t number_of_part_definitions = part_definitions.size();
+  WriteUnsignedInteger (number_of_part_definitions)
+  for (uint32_t i=0;i<number_of_part_definitions;i++)
+    SerializePartDefinition (part_definitions[i])
+       
+  const uint32_t number_of_product_occurrences = product_occurrences.size();
+  WriteUnsignedInteger (number_of_product_occurrences)
+  for (uint32_t i=0;i<number_of_product_occurrences;i++)
+  {
+    product_occurrences[i]->unit_information.unit_from_CAD_file = true;
+    product_occurrences[i]->unit_information.unit = unit;
+    SerializeProductOccurrence (product_occurrences[i])
+  }
+
+  // SerializeFileStructureInternalData
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructure)
+  SerializeEmptyContentPRCBase
+  const uint32_t next_available_index = makePRCID();
+  WriteUnsignedInteger (next_available_index)
+  const uint32_t index_product_occurence = number_of_product_occurrences;  // Asymptote (oPRCFile) specific - we write the root product last
+  WriteUnsignedInteger (index_product_occurence)
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureTessellation(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureTessellation)
+
+  SerializeEmptyContentPRCBase
+  const uint32_t number_of_tessellations = tessellations.size();
+  WriteUnsignedInteger (number_of_tessellations)
+  for (uint32_t i=0;i<number_of_tessellations;i++)
+    tessellations[i]->serializeBaseTessData(out);
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureGeometry(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureGeometry)
+
+  SerializeEmptyContentPRCBase
+  const uint32_t number_of_contexts = contexts.size();
+  WriteUnsignedInteger (number_of_contexts)
+  for (uint32_t i=0;i<number_of_contexts;i++)
+    SerializeContextAndBodies (contexts[i])
+
+  SerializeUserData
+}
+
+void PRCFileStructure::serializeFileStructureExtraGeometry(PRCbitStream &out)
+{
+  WriteUnsignedInteger (PRC_TYPE_ASM_FileStructureExtraGeometry)
+
+  SerializeEmptyContentPRCBase
+  const uint32_t number_of_contexts = contexts.size();
+  WriteUnsignedInteger (number_of_contexts)
+  for (uint32_t i=0;i<number_of_contexts;i++)
+  {
+     SerializeGeometrySummary (contexts[i])
+     SerializeContextGraphics (contexts[i])
+  }
+
+  SerializeUserData
+}
+
+void oPRCFile::serializeModelFileData(PRCbitStream &out)
+{
+  // even though this is technically not part of this section,
+  // it is handled here for convenience
+  const uint32_t number_of_schema = 0;
+  WriteUnsignedInteger (number_of_schema)
+  WriteUnsignedInteger (PRC_TYPE_ASM_ModelFile)
+
+  PRCSingleAttribute sa((int32_t)PRCVersion);
+  PRCAttribute a("__PRC_RESERVED_ATTRIBUTE_PRCInternalVersion");
+  a.addKey(sa);
+  ContentPRCBase cb(PRC_TYPE_ROOT_PRCBase,"PRC file");
+  cb.addAttribute(a);
+  cb.serializeContentPRCBase(out);
+
+  SerializeUnit (unit)
+
+  out << (uint32_t)1; // 1 product occurrence
+  //UUID
+  SerializeCompressedUniqueId( fileStructures[0]->file_structure_uuid )
+  // index+1
+  out << (uint32_t)fileStructures[0]->product_occurrences.size();
+  // active
+  out << true;
+  out << (uint32_t)0; // index in model file
+
+  SerializeUserData
+}
+
+void makeFileUUID(PRCUniqueId& UUID)
+{
+  // make a UUID
+  static uint32_t count = 0;
+  ++count;
+  // the minimum requirement on UUIDs is that all must be unique in the file
+  UUID.id0 = 0x33595341; // some constant
+  UUID.id1 = (uint32_t)time(NULL); // the time
+  UUID.id2 = count;
+  UUID.id3 = 0xa5a55a5a; // Something random, not seeded by the time, would be nice. But for now, a constant
+  // maybe add something else to make it more unique
+  // so multiple files can be combined
+  // a hash of some data perhaps?
+}
+
+void makeAppUUID(PRCUniqueId& UUID)
+{
+  UUID.id0 = UUID.id1 = UUID.id2 = UUID.id3 = 0;
+}
+
+void PRCUncompressedFile::write(ostream &out) const
+{
+  if(data!=NULL)
+  {
+    WriteUncompressedUnsignedInteger (file_size)
+    out.write((char*)data,file_size);
+  }
+}
+
+uint32_t PRCUncompressedFile::getSize() const
+{
+  return sizeof(file_size)+file_size;
+}
+
+
+void PRCStartHeader::serializeStartHeader(ostream &out) const
+{
+  WriteUncompressedBlock ("PRC",3)
+  WriteUncompressedUnsignedInteger (minimal_version_for_read)
+  WriteUncompressedUnsignedInteger (authoring_version)
+  SerializeFileStructureUncompressedUniqueId( file_structure_uuid );
+  SerializeFileStructureUncompressedUniqueId( application_uuid );
+}
+
+uint32_t PRCStartHeader::getStartHeaderSize() const
+{
+  return 3+(2+2*4)*sizeof(uint32_t);
+}
+
+
+void PRCFileStructure::write(ostream &out)
+{
+  // SerializeFileStructureHeader
+  SerializeStartHeader
+  SerializeUncompressedFiles
+  globals_out.write(out);
+  tree_out.write(out);
+  tessellations_out.write(out);
+  geometry_out.write(out);
+  extraGeometry_out.write(out);
+}
+
+#define SerializeFileStructureGlobals serializeFileStructureGlobals(globals_out); globals_out.compress(); sizes[1]=globals_out.getSize();
+#define SerializeFileStructureTree serializeFileStructureTree(tree_out); tree_out.compress(); sizes[2]=tree_out.getSize();
+#define SerializeFileStructureTessellation serializeFileStructureTessellation(tessellations_out); tessellations_out.compress(); sizes[3]=tessellations_out.getSize();
+#define SerializeFileStructureGeometry serializeFileStructureGeometry(geometry_out); geometry_out.compress(); sizes[4]=geometry_out.getSize();
+#define SerializeFileStructureExtraGeometry serializeFileStructureExtraGeometry(extraGeometry_out); extraGeometry_out.compress(); sizes[5]=extraGeometry_out.getSize();
+#define FlushSerialization resetGraphicsAndName();
+void PRCFileStructure::prepare()
+{
+  uint32_t size = 0;
+  size += getStartHeaderSize();
+  size += sizeof(uint32_t);
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+    size += (*it)->getSize();
+  sizes[0]=size;
+
+  SerializeFileStructureGlobals
+  FlushSerialization
+
+  SerializeFileStructureTree
+  FlushSerialization
+
+  SerializeFileStructureTessellation
+  FlushSerialization
+
+  SerializeFileStructureGeometry
+  FlushSerialization
+
+  SerializeFileStructureExtraGeometry
+  FlushSerialization
+}
+
+uint32_t PRCFileStructure::getSize()
+{
+  uint32_t size = 0;
+  for(size_t i=0; i<6; i++)
+    size += sizes[i];
+  return size;
+}
+
+
+void PRCFileStructureInformation::write(ostream &out)
+{
+  SerializeFileStructureUncompressedUniqueId( UUID );
+
+  WriteUncompressedUnsignedInteger (reserved)
+  WriteUncompressedUnsignedInteger (number_of_offsets)
+  for(uint32_t i = 0; i < number_of_offsets; ++i)
+  {
+    WriteUncompressedUnsignedInteger (offsets[i])
+  }
+}
+
+uint32_t PRCFileStructureInformation::getSize()
+{
+  return (4+2+number_of_offsets)*sizeof(uint32_t);
+}
+
+void PRCHeader::write(ostream &out)
+{
+  SerializeStartHeader
+  WriteUncompressedUnsignedInteger (number_of_file_structures)
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+  {
+    fileStructureInformation[i].write(out);
+  }
+  WriteUncompressedUnsignedInteger (model_file_offset)
+  WriteUncompressedUnsignedInteger (file_size)
+  SerializeUncompressedFiles
+}
+
+uint32_t PRCHeader::getSize()
+{
+  uint32_t size = getStartHeaderSize() + sizeof(uint32_t);
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+    size += fileStructureInformation[i].getSize();
+  size += 3*sizeof(uint32_t);
+  for(PRCUncompressedFileList::const_iterator it = uncompressed_files.begin(); it != uncompressed_files.end(); it++)
+    size += (*it)->getSize();
+  return size;
+}
+
+void oPRCFile::doGroup(PRCgroup& group)
+{
+    const string& name = group.name;
+
+    PRCProductOccurrence*& product_occurrence        = group.product_occurrence;
+    PRCProductOccurrence*& parent_product_occurrence = group.parent_product_occurrence;
+    PRCPartDefinition*& part_definition              = group.part_definition;
+    PRCPartDefinition*& parent_part_definition       = group.parent_part_definition;
+
+    if(group.options.tess)
+    {
+      if(!group.lines.empty())
+      {
+        for(PRCtesslineMap::const_iterator wit=group.lines.begin(); wit!=group.lines.end(); wit++)
+        {
+          bool same_color = true;
+          const PRCtesslineList& lines = wit->second;
+          const PRCRgbColor &color = lines.front().color;
+          for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
+            if(color!=lit->color)
+            {
+              same_color = false;
+              break;
+            }
+          map<PRCVector3d,uint32_t> points;
+          PRC3DWireTess *tess = new PRC3DWireTess();
+          if(!same_color)
+          {
+            tess->is_segment_color = true;
+            tess->is_rgba = false;
+          }
+          for(PRCtesslineList::const_iterator lit=lines.begin(); lit!=lines.end(); lit++)
+          {
+            tess->wire_indexes.push_back(lit->point.size());
+            for(uint32_t i=0; i<lit->point.size(); i++)
+            {
+              map<PRCVector3d,uint32_t>::iterator pPoint = points.find(lit->point[i]);
+              if(pPoint!=points.end())
+                tess->wire_indexes.push_back(pPoint->second);
+              else
+              {
+                const uint32_t point_index = tess->coordinates.size();
+                points.insert(make_pair(lit->point[i],point_index));
+                tess->wire_indexes.push_back(point_index);
+                tess->coordinates.push_back(lit->point[i].x);
+                tess->coordinates.push_back(lit->point[i].y);
+                tess->coordinates.push_back(lit->point[i].z);
+              }
+              if(!same_color && i>0)
+              {
+                tess->rgba_vertices.push_back(byte(lit->color.red));
+                tess->rgba_vertices.push_back(byte(lit->color.green));
+                tess->rgba_vertices.push_back(byte(lit->color.blue));
+              }
+            }
+          }
+          const uint32_t tess_index = add3DWireTess(tess);
+          PRCPolyWire *polyWire = new PRCPolyWire();
+          polyWire->index_tessellation = tess_index;
+          if(same_color)
+            polyWire->index_of_line_style = addColourWidth(RGBAColour(color.red,color.green,color.blue),wit->first);
+          else
+            polyWire->index_of_line_style = addColourWidth(RGBAColour(1,1,1),wit->first);
+          part_definition->addPolyWire(polyWire);
+        }
+      }
+//    make rectangles pairs of triangles in a tesselation
+      if(!group.rectangles.empty())
+      {
+        bool same_color = true;
+        const uint32_t &style = group.rectangles.front().style;
+        for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+          if(style!=rit->style)
+          {
+            same_color = false;
+            break;
+          }
+        map<PRCVector3d,uint32_t> points;
+        PRC3DTess *tess = new PRC3DTess();
+        PRCTessFace *tessFace = new PRCTessFace();
+        tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+        uint32_t triangles = 0;
+        for(PRCtessrectangleList::const_iterator rit=group.rectangles.begin(); rit!=group.rectangles.end(); rit++)
+        {
+          const bool degenerate = (rit->vertices[0]==rit->vertices[1]);
+          uint32_t vertex_indices[4];
+          for(size_t i = (degenerate?1:0); i < 4; ++i)
+          {
+            map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(rit->vertices[i]);
+            if(pPoint!=points.end())
+              vertex_indices[i] =  pPoint->second;
+            else
+            {
+              points.insert(make_pair(rit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+              tess->coordinates.push_back(rit->vertices[i].x);
+              tess->coordinates.push_back(rit->vertices[i].y);
+              tess->coordinates.push_back(rit->vertices[i].z);
+            }
+          }
+          if(degenerate)
+          {
+            tess->triangulated_index.push_back(vertex_indices[1]);
+            tess->triangulated_index.push_back(vertex_indices[2]);
+            tess->triangulated_index.push_back(vertex_indices[3]);
+            triangles++;
+            if(!same_color)
+              tessFace->line_attributes.push_back(rit->style);
+          }
+          else
+          {
+            tess->triangulated_index.push_back(vertex_indices[0]);
+            tess->triangulated_index.push_back(vertex_indices[2]);
+            tess->triangulated_index.push_back(vertex_indices[3]);
+            triangles++;
+            if(!same_color)
+              tessFace->line_attributes.push_back(rit->style);
+            tess->triangulated_index.push_back(vertex_indices[3]);
+            tess->triangulated_index.push_back(vertex_indices[1]);
+            tess->triangulated_index.push_back(vertex_indices[0]);
+            triangles++;
+            if(!same_color)
+              tessFace->line_attributes.push_back(rit->style);
+          }
+        }
+        tessFace->sizes_triangulated.push_back(triangles);
+        tess->addTessFace(tessFace);
+        const uint32_t tess_index = add3DTess(tess);
+        PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+        polyBrepModel->index_tessellation = tess_index;
+        polyBrepModel->is_closed = group.options.closed;
+        if(same_color)
+          polyBrepModel->index_of_line_style = style;
+        part_definition->addPolyBrepModel(polyBrepModel);
+      }
+    }
+
+    if(!group.quads.empty())
+    {
+      map<PRCVector3d,uint32_t> points;
+      PRC3DTess *tess = new PRC3DTess();
+      PRCTessFace *tessFace = new PRCTessFace();
+      tessFace->used_entities_flag=PRC_FACETESSDATA_Triangle;
+      uint32_t triangles = 0;
+
+      tessFace->is_rgba = false;
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        if(C[0].A != 1.0 || C[1].A != 1.0 || C[2].A != 1.0 || C[3].A != 1.0)
+        {
+          tessFace->is_rgba = true;
+          break;
+        }
+      }
+      bool same_colour = true;
+      const RGBAColour& colour = group.quads.front().colours[0];
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        if(colour!=C[0] || colour!=C[1] || colour!=C[2] || colour!=C[3])
+        {
+          same_colour = false;
+          break;
+        }
+      }
+      
+      for(PRCtessquadList::const_iterator qit=group.quads.begin(); qit!=group.quads.end(); qit++)
+      {
+        const RGBAColour* C = qit->colours;
+        const bool degenerate = (qit->vertices[0]==qit->vertices[1]);
+        uint32_t vertex_indices[4];
+        for(size_t i = (degenerate?1:0); i < 4; ++i)
+        {
+          map<PRCVector3d,uint32_t>::const_iterator pPoint = points.find(qit->vertices[i]);
+          if(pPoint!=points.end())
+            vertex_indices[i] =  pPoint->second;
+          else
+          {
+            points.insert(make_pair(qit->vertices[i],(vertex_indices[i] = tess->coordinates.size())));
+            tess->coordinates.push_back(qit->vertices[i].x);
+            tess->coordinates.push_back(qit->vertices[i].y);
+            tess->coordinates.push_back(qit->vertices[i].z);
+          }
+        }
+        if(degenerate)
+        {
+          tess->triangulated_index.push_back(vertex_indices[1]);
+          tess->triangulated_index.push_back(vertex_indices[2]);
+          tess->triangulated_index.push_back(vertex_indices[3]);
+          triangles++;
+          if(!same_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[1].R));
+            tessFace->rgba_vertices.push_back(byte(C[1].G));
+            tessFace->rgba_vertices.push_back(byte(C[1].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[1].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[2].R));
+            tessFace->rgba_vertices.push_back(byte(C[2].G));
+            tessFace->rgba_vertices.push_back(byte(C[2].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[2].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          }
+        }
+        else
+        {
+          tess->triangulated_index.push_back(vertex_indices[0]);
+          tess->triangulated_index.push_back(vertex_indices[2]);
+          tess->triangulated_index.push_back(vertex_indices[3]);
+          triangles++;
+          if(!same_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[0].R));
+            tessFace->rgba_vertices.push_back(byte(C[0].G));
+            tessFace->rgba_vertices.push_back(byte(C[0].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[0].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[2].R));
+            tessFace->rgba_vertices.push_back(byte(C[2].G));
+            tessFace->rgba_vertices.push_back(byte(C[2].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[2].A));
+            
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          }
+          tess->triangulated_index.push_back(vertex_indices[3]);
+          tess->triangulated_index.push_back(vertex_indices[1]);
+          tess->triangulated_index.push_back(vertex_indices[0]);
+          triangles++;
+          if(!same_colour)
+          {
+            tessFace->rgba_vertices.push_back(byte(C[3].R));
+            tessFace->rgba_vertices.push_back(byte(C[3].G));
+            tessFace->rgba_vertices.push_back(byte(C[3].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[3].A));
+          
+            tessFace->rgba_vertices.push_back(byte(C[1].R));
+            tessFace->rgba_vertices.push_back(byte(C[1].G));
+            tessFace->rgba_vertices.push_back(byte(C[1].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[1].A));
+          
+            tessFace->rgba_vertices.push_back(byte(C[0].R));
+            tessFace->rgba_vertices.push_back(byte(C[0].G));
+            tessFace->rgba_vertices.push_back(byte(C[0].B));
+            if(tessFace->is_rgba)
+              tessFace->rgba_vertices.push_back(byte(C[0].A));
+          }
+        }
+      }
+      tessFace->sizes_triangulated.push_back(triangles);
+      tess->addTessFace(tessFace);
+      const uint32_t tess_index = add3DTess(tess);
+      PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+      polyBrepModel->index_tessellation = tess_index;
+      polyBrepModel->is_closed = group.options.closed;
+      if(same_colour)
+        polyBrepModel->index_of_line_style = addColour(colour);
+      part_definition->addPolyBrepModel(polyBrepModel);
+    }
+
+    if(!group.points.empty())
+    {
+      for(PRCpointsetMap::const_iterator pit=group.points.begin(); pit!=group.points.end(); pit++)
+      {
+        PRCPointSet *pointset = new PRCPointSet();
+        pointset->index_of_line_style = pit->first;
+        pointset->point = pit->second;
+        part_definition->addPointSet(pointset);
+      }
+    }
+
+    if(!group.pointsets.empty())
+    {
+      for(std::vector<PRCPointSet*>::iterator pit=group.pointsets.begin(); pit!=group.pointsets.end(); pit++)
+      {
+        part_definition->addPointSet(*pit);
+      }
+    }
+
+    if(!group.polymodels.empty())
+    {
+      for(std::vector<PRCPolyBrepModel*>::iterator pit=group.polymodels.begin(); pit!=group.polymodels.end(); pit++)
+      {
+        part_definition->addPolyBrepModel(*pit);
+      }
+    }
+
+    if(!group.polywires.empty())
+    {
+      for(std::vector<PRCPolyWire*>::iterator pit=group.polywires.begin(); pit!=group.polywires.end(); pit++)
+      {
+        part_definition->addPolyWire(*pit);
+      }
+    }
+
+    if(!group.wires.empty())
+    {
+      PRCTopoContext *wireContext = NULL;
+      const uint32_t context_index = getTopoContext(wireContext);
+      for(PRCwireList::iterator wit=group.wires.begin(); wit!=group.wires.end(); wit++)
+      {
+        PRCWireEdge *wireEdge = new PRCWireEdge;
+        wireEdge->curve_3d = wit->curve;
+        PRCSingleWireBody *wireBody = new PRCSingleWireBody;
+        wireBody->setWireEdge(wireEdge);
+        const uint32_t wire_body_index = wireContext->addSingleWireBody(wireBody);
+        PRCWire *wire = new PRCWire();
+        wire->index_of_line_style = wit->style;
+        wire->context_id = context_index;
+        wire->body_id = wire_body_index;
+        if(wit->transform)
+            wire->index_local_coordinate_system = addTransform(wit->transform);
+        part_definition->addWire(wire);
+      }
+    }
+
+    PRCfaceList &faces = group.faces;
+    if(!faces.empty())
+    {
+      bool same_color = true;
+      const uint32_t style = faces.front().style;
+      for(PRCfaceList::const_iterator fit=faces.begin(); fit!=faces.end(); fit++)
+        if(style!=fit->style)
+        {
+          same_color = false;
+          break;
+        }
+      PRCTopoContext *context = NULL;
+      const uint32_t context_index = getTopoContext(context);
+      context->granularity = group.options.granularity;
+   // Acrobat 9 also does the following:
+   // context->tolerance = group.options.granularity;
+   // context->have_smallest_face_thickness = true;
+   // context->smallest_thickness = group.options.granularity;
+      PRCShell *shell = new PRCShell;
+
+      for(PRCfaceList::iterator fit=faces.begin(); fit!=faces.end(); fit++)
+      {
+        if(fit->transform || group.options.do_break ||
+           (fit->transparent && !group.options.no_break))
+        {
+          PRCShell *shell = new PRCShell;
+          shell->addFace(fit->face);
+          PRCConnex *connex = new PRCConnex;
+          connex->addShell(shell);
+          PRCBrepData *body = new PRCBrepData;
+          body->addConnex(connex);
+          const uint32_t body_index = context->addBrepData(body);
+
+          PRCBrepModel *brepmodel = new PRCBrepModel();
+          brepmodel->index_of_line_style = fit->style;
+          brepmodel->context_id = context_index;
+          brepmodel->body_id = body_index;
+          brepmodel->is_closed = group.options.closed;
+
+          brepmodel->index_local_coordinate_system = addTransform(fit->transform);
+
+          part_definition->addBrepModel(brepmodel);
+        }
+        else
+        {
+          if(!same_color)
+            fit->face->index_of_line_style = fit->style;
+          shell->addFace(fit->face);
+        }
+      }
+      if(shell->face.empty())
+      {
+        delete shell;
+      }
+      else
+      {
+        PRCConnex *connex = new PRCConnex;
+        connex->addShell(shell);
+        PRCBrepData *body = new PRCBrepData;
+        body->addConnex(connex);
+        const uint32_t body_index = context->addBrepData(body);
+        PRCBrepModel *brepmodel = new PRCBrepModel();
+        if(same_color)
+          brepmodel->index_of_line_style = style;
+        brepmodel->context_id = context_index;
+        brepmodel->body_id = body_index;
+        brepmodel->is_closed = group.options.closed;
+        part_definition->addBrepModel(brepmodel);
+      }
+    }
+
+    PRCcompfaceList &compfaces = group.compfaces;
+    if(!compfaces.empty())
+    {
+      bool same_color = true;
+      const uint32_t style = compfaces.front().style;
+      for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+        if(style!=fit->style)
+        {
+          same_color = false;
+          break;
+        }
+      PRCTopoContext *context = NULL;
+      const uint32_t context_index = getTopoContext(context);
+      PRCCompressedBrepData *body = new PRCCompressedBrepData;
+
+      body->serial_tolerance=group.options.compression;
+      body->brep_data_compressed_tolerance=0.1*group.options.compression;
+
+      for(PRCcompfaceList::const_iterator fit=compfaces.begin(); fit!=compfaces.end(); fit++)
+      {
+        if(group.options.do_break ||
+           (fit->transparent && !group.options.no_break))
+        {
+          PRCCompressedBrepData *body = new PRCCompressedBrepData;
+          body->face.push_back(fit->face);
+
+          body->serial_tolerance=group.options.compression;
+          body->brep_data_compressed_tolerance=2.8346456*
+            group.options.compression;
+          const uint32_t body_index = context->addCompressedBrepData(body);
+
+          PRCBrepModel *brepmodel = new PRCBrepModel();
+          brepmodel->index_of_line_style = fit->style;
+          brepmodel->context_id = context_index;
+          brepmodel->body_id = body_index;
+          brepmodel->is_closed = group.options.closed;
+
+          part_definition->addBrepModel(brepmodel);
+        }
+        else
+        {
+          if(!same_color)
+            fit->face->index_of_line_style = fit->style;
+          body->face.push_back(fit->face);
+        }
+      }
+      if(body->face.empty())
+      {
+        delete body;
+      }
+      else
+      {
+        const uint32_t body_index = context->addCompressedBrepData(body);
+        PRCBrepModel *brepmodel = new PRCBrepModel();
+        if(same_color)
+          brepmodel->index_of_line_style = style;
+        brepmodel->context_id = context_index;
+        brepmodel->body_id = body_index;
+        brepmodel->is_closed = group.options.closed;
+        part_definition->addBrepModel(brepmodel);
+      }
+    }
+
+    // Simplify and reduce to as simple entities as possible
+    // products with named representation items can not be reduced to sets, since 
+    // outside references are already set
+    bool nonamedparts = true;
+    for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+    {
+      if (!(*it)->name.empty())
+      {
+        nonamedparts = false;
+        break;
+      }
+    }
+    lastgroupname.clear();
+    lastgroupnames.clear();
+    // First option - reduce to one element in parent
+    if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+        part_definition->representation_item.size() == 1 &&
+        ( name.empty() || part_definition->representation_item.front()->name.empty() ) &&
+        ( !group.transform  || part_definition->representation_item.front()->index_local_coordinate_system==m1) )
+    {
+      if(part_definition->representation_item.front()->name.empty() )
+        part_definition->representation_item.front()->name = name;
+      if(part_definition->representation_item.front()->index_local_coordinate_system==m1)
+        part_definition->representation_item.front()->index_local_coordinate_system = addTransform(group.transform);
+      lastgroupname = calculate_unique_name(part_definition->representation_item.front(), parent_product_occurrence);
+      parent_part_definition->addRepresentationItem(part_definition->representation_item.front());
+      part_definition->representation_item.clear();
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
+    }
+    // Second option - reduce to a set
+    else if (parent_part_definition && product_occurrence->index_son_occurrence.empty() &&
+      !part_definition->representation_item.empty() &&
+      !group.options.do_break && nonamedparts)
+    {
+      PRCSet *set = new PRCSet(name);
+      set->index_local_coordinate_system = addTransform(group.transform);
+      lastgroupname = calculate_unique_name(set, parent_product_occurrence);
+      for(PRCRepresentationItemList::iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+      {
+        lastgroupnames.push_back(calculate_unique_name(*it, parent_product_occurrence));
+        set->addRepresentationItem(*it);
+      }
+      part_definition->representation_item.clear();
+      parent_part_definition->addSet(set);
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
+    }
+    // Third option - create product
+    else if ( !product_occurrence->index_son_occurrence.empty() || !part_definition->representation_item.empty())
+    {
+      // if everything is enclosed in one group - drop the root group
+      if (parent_product_occurrence == NULL && group.transform == NULL &&
+          part_definition->representation_item.empty() && product_occurrence->index_son_occurrence.size()==1) {
+        delete part_definition; part_definition = NULL;
+        delete product_occurrence; product_occurrence = NULL;
+      }
+      else
+      {
+        lastgroupname = calculate_unique_name(product_occurrence, NULL);
+        if (part_definition->representation_item.empty()) {
+          delete part_definition; part_definition = NULL;
+        }
+        else
+        {
+          for(PRCRepresentationItemList::const_iterator it=part_definition->representation_item.begin(); it!=part_definition->representation_item.end(); it++)
+            if ((*it)->name.empty())
+              lastgroupnames.push_back(calculate_unique_name(*it, product_occurrence));
+          product_occurrence->index_part = addPartDefinition(part_definition);
+        }
+        if (group.transform) {
+          product_occurrence->location = group.transform;
+          group.transform = NULL;
+        }
+        if (parent_product_occurrence) {
+          parent_product_occurrence->index_son_occurrence.push_back(addProductOccurrence(product_occurrence));
+        }
+        else {
+          addProductOccurrence(product_occurrence);
+        }
+      }
+    }
+    // Last case - absolutely nothing to do
+    else
+    {
+      delete product_occurrence; product_occurrence = NULL;
+      delete part_definition; part_definition = NULL;
+    }
+
+}
+
+std::string oPRCFile::calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence)
+{
+  std::stringstream ss (std::stringstream::in | std::stringstream::out);
+  uint8_t *serialization_buffer = NULL;
+  PRCbitStream serialization(serialization_buffer,0u);
+  const PRCFileStructure *pfile_structure = fileStructures[0];
+  const PRCUniqueId& uuid = pfile_structure->file_structure_uuid;
+// ConvertUniqueIdentifierToString (prc_entity)
+// SerializeCompressedUniqueId (file_structure)
+  serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+  serialization << prc_entity->getType();
+// WriteUnsignedInteger (unique_identifier)
+  serialization << prc_entity->getPRCID();
+  if (prc_occurence)
+  {
+// serialization_buffer = Flush serialization (serialization) 
+  {
+    const uint32_t size_serialization = serialization.getSize();
+    while(size_serialization == serialization.getSize())
+      serialization << false;
+  }
+// ConvertUniqueIdentifierToString (prc_occurrence_unique_id)
+// SerializeCompressedUniqueId (file_structure)
+    serialization << uuid.id0 << uuid.id1 << uuid.id2 << uuid.id3;
+// WriteUnsignedInteger (type)
+    serialization << (uint32_t)PRC_TYPE_ASM_ProductOccurence;
+// WriteUnsignedInteger (unique_identifier)
+    serialization << prc_occurence->getPRCID();
+  }
+  ss << (prc_entity->name.empty()?"node":prc_entity->name) << '.';
+  const uint32_t size_serialization = serialization.getSize();
+  for(size_t j=0; j<size_serialization; j++)
+    ss << hex << setfill('0') << setw(2) << (uint32_t)(serialization_buffer[j]);
+
+  return ss.str();
+}
+
+bool oPRCFile::finish()
+{
+  if(groups.size()!=1) {
+    fputs("begingroup without matching endgroup",stderr);
+    exit(1);
+  }
+  doGroup(groups.top());
+
+  // write each section's bit data
+  fileStructures[0]->prepare();
+  SerializeModelFileData
+
+  // create the header
+
+  // fill out enough info so that sizes can be computed correctly
+  header.number_of_file_structures = number_of_file_structures;
+  header.fileStructureInformation = new PRCFileStructureInformation[number_of_file_structures];
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+  {
+    header.fileStructureInformation[i].UUID = fileStructures[i]->file_structure_uuid;
+    header.fileStructureInformation[i].reserved = 0;
+    header.fileStructureInformation[i].number_of_offsets = 6;
+    header.fileStructureInformation[i].offsets = new uint32_t[6];
+  }
+
+  header.minimal_version_for_read = PRCVersion;
+  header.authoring_version = PRCVersion;
+  makeFileUUID(header.file_structure_uuid);
+  makeAppUUID(header.application_uuid);
+
+  header.file_size = getSize();
+  header.model_file_offset = header.file_size - modelFile_out.getSize();
+
+  uint32_t currentOffset = header.getSize();
+
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+  {
+    for(size_t j=0; j<6; j++)
+    {
+      header.fileStructureInformation[i].offsets[j] = currentOffset;
+      currentOffset += fileStructures[i]->sizes[j];
+    }
+  }
+
+  // write the data
+  header.write(output);
+
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+  {
+    fileStructures[i]->write(output);
+  }
+
+  modelFile_out.write(output);
+  output.flush();
+
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+    delete[] header.fileStructureInformation[i].offsets;
+  delete[] header.fileStructureInformation;
+
+  return true;
+}
+
+uint32_t oPRCFile::getSize()
+{
+  uint32_t size = header.getSize();
+
+  for(uint32_t i = 0; i < number_of_file_structures; ++i)
+  {
+    size += fileStructures[i]->getSize();
+  }
+
+  size += modelFile_out.getSize();
+  return size;
+}
+
+uint32_t PRCFileStructure::addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t *p, uint32_t width, uint32_t height, string name)
+{
+  uint8_t *data = NULL;
+  uint32_t components=0;
+  PRCPicture picture(name);
+  if(size==0 || p==NULL)
+  { cerr << "image not set" << endl; return m1; }
+  PRCUncompressedFile* uncompressed_file = new PRCUncompressedFile;
+  if(format==KEPRCPicture_PNG || format==KEPRCPicture_JPG)
+  {
+    data = new uint8_t[size];
+    memcpy(data, p, size);
+    uncompressed_files.push_back(uncompressed_file);
+    uncompressed_files.back()->file_size = size;
+    uncompressed_files.back()->data = data;
+    picture.format = format;
+    picture.uncompressed_file_index = uncompressed_files.size()-1;
+    picture.pixel_width = 0; // width and height are ignored for JPG and PNG pictures - but let us keep things clean
+    picture.pixel_height = 0;
+    pictures.push_back(picture);
+    return pictures.size()-1;
+  }
+
+  switch(format)
+  {
+    case KEPRCPicture_BITMAP_RGB_BYTE:
+      components = 3; break;
+    case KEPRCPicture_BITMAP_RGBA_BYTE:
+      components = 4; break;
+    case KEPRCPicture_BITMAP_GREY_BYTE:
+      components = 1; break;
+    case KEPRCPicture_BITMAP_GREYA_BYTE:
+      components = 2; break;
+    default:
+      { cerr << "unknown picture format" << endl; return m1; }
+  }
+  if(width==0 || height==0)
+    { cerr << "width or height parameter not set" << endl; return m1; }
+  if (size < width*height*components)
+    { cerr << "image too small" << endl; return m1; }
+
+  {
+    uint32_t compressedDataSize = 0;
+    const int CHUNK= 1024; // is this reasonable?
+
+    z_stream strm;
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    if(deflateInit(&strm,Z_DEFAULT_COMPRESSION) != Z_OK)
+      { cerr << "Compression initialization failed" << endl; return m1; }
+    unsigned int sizeAvailable = deflateBound(&strm,size);
+    uint8_t *compressedData = (uint8_t*) malloc(sizeAvailable);
+    strm.avail_in = size;
+    strm.next_in = (unsigned char*)p;
+    strm.next_out = (unsigned char*)compressedData;
+    strm.avail_out = sizeAvailable;
+
+    int code;
+    unsigned int chunks = 0;
+    while((code = deflate(&strm,Z_FINISH)) == Z_OK)
+    {
+      ++chunks;
+      // strm.avail_out should be 0 if we got Z_OK
+      compressedDataSize = sizeAvailable - strm.avail_out;
+      compressedData = (uint8_t*) realloc(compressedData,CHUNK*chunks);
+      strm.next_out = (Bytef*)(compressedData + compressedDataSize);
+      strm.avail_out += CHUNK;
+      sizeAvailable += CHUNK;
+    }
+    compressedDataSize = sizeAvailable-strm.avail_out;
+
+    if(code != Z_STREAM_END)
+    {
+      deflateEnd(&strm);
+      free(compressedData);
+      { cerr << "Compression error" << endl; return m1; }
+    }
+
+    deflateEnd(&strm);
+    size = compressedDataSize;
+    data = new uint8_t[compressedDataSize];
+    memcpy(data, compressedData, compressedDataSize);
+    free(compressedData);
+  }
+  uncompressed_files.push_back(uncompressed_file);
+  uncompressed_files.back()->file_size = size;
+  uncompressed_files.back()->data = data;
+  picture.format = format;
+  picture.uncompressed_file_index = uncompressed_files.size()-1;
+  picture.pixel_width = width;
+  picture.pixel_height = height;
+  pictures.push_back(picture);
+  return pictures.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureDefinition(PRCTextureDefinition*& pTextureDefinition)
+{
+  texture_definitions.push_back(pTextureDefinition);
+  pTextureDefinition = NULL;
+  return texture_definitions.size()-1;
+}
+
+uint32_t PRCFileStructure::addRgbColor(const PRCRgbColor &color)
+{
+  colors.push_back(color);
+  return 3*(colors.size()-1);
+}
+
+uint32_t PRCFileStructure::addRgbColorUnique(const PRCRgbColor &color)
+{
+  for(uint32_t i = 0; i < colors.size(); ++i)
+  {
+    if(colors[i] == color)
+      return 3*i;
+  }
+  colors.push_back(color);
+  return 3*(colors.size()-1);
+}
+
+uint32_t oPRCFile::addColor(const PRCRgbColor &color)
+{
+  PRCcolorMap::const_iterator pColor = colorMap.find(color);
+  if(pColor!=colorMap.end())
+    return pColor->second;
+//  color_index = addRgbColorUnique(color);
+  const uint32_t color_index = fileStructures[0]->addRgbColor(color);
+  colorMap.insert(make_pair(color,color_index));
+  return color_index;
+}
+
+uint32_t oPRCFile::addColour(const RGBAColour &colour)
+{
+  PRCcolourMap::const_iterator pColour = colourMap.find(colour);
+  if(pColour!=colourMap.end())
+    return pColour->second;
+  const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+  PRCStyle *style = new PRCStyle();
+  style->line_width = 1.0;
+  style->is_vpicture = false;
+  style->line_pattern_vpicture_index = 0;
+  style->is_material = false;
+  style->color_material_index = color_index;
+  style->is_transparency_defined = (colour.A < 1.0);
+  style->transparency = (uint8_t)(colour.A * 256);
+  style->additional = 0;
+  const uint32_t style_index = fileStructures[0]->addStyle(style);
+  colourMap.insert(make_pair(colour,style_index));
+  return style_index;
+}
+
+uint32_t oPRCFile::addColourWidth(const RGBAColour &colour, double width)
+{
+  RGBAColourWidth colourwidth(colour.R, colour.G, colour.B, colour.A, width);
+  PRCcolourwidthMap::const_iterator pColour = colourwidthMap.find(colourwidth);
+  if(pColour!=colourwidthMap.end())
+    return pColour->second;
+  const uint32_t color_index = addColor(PRCRgbColor(colour.R, colour.G, colour.B));
+  PRCStyle *style = new PRCStyle();
+  style->line_width = width;
+  style->is_vpicture = false;
+  style->line_pattern_vpicture_index = 0;
+  style->is_material = false;
+  style->color_material_index = color_index;
+  style->is_transparency_defined = (colour.A < 1.0);
+  style->transparency = (uint8_t)(colour.A * 256);
+  style->additional = 0;
+  const uint32_t style_index = fileStructures[0]->addStyle(style);
+  colourwidthMap.insert(make_pair(colourwidth,style_index));
+  return style_index;
+}
+
+uint32_t oPRCFile::addTransform(PRCGeneralTransformation3d*& transform)
+{
+  if(!transform)
+    return m1;
+  PRCtransformMap::const_iterator pTransform = transformMap.find(*transform);
+  if(pTransform!=transformMap.end())
+    return pTransform->second;
+  PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+  bool transform_replaced = false;
+  if(                            transform->M(0,1)==0 && transform->M(0,2)==0 &&
+      transform->M(1,0)==0 &&                            transform->M(1,2)==0 &&
+      transform->M(2,0)==0 && transform->M(2,1)==0 &&
+      transform->M(3,0)==0 && transform->M(3,1)==0 && transform->M(3,2)==0 && transform->M(3,3)==1 )
+  {
+    transform_replaced = true;
+    PRCCartesianTransformation3d *carttransform = new PRCCartesianTransformation3d;
+//  if(transform->M(0,3)==0 && transform->M(1,3)==0 && transform->M(1,3)==0 &&
+//     transform->M(0,0)==1 && transform->M(1,1)==1 && transform->M(2,2)==1 )
+//    carttransform->behaviour = PRC_TRANSFORMATION_Identity;
+    if(transform->M(0,3)!=0 || transform->M(1,3)!=0 || transform->M(2,3)!=0)
+    {
+      carttransform->behaviour |= PRC_TRANSFORMATION_Translate;
+      carttransform->origin.Set(transform->M(0,3),transform->M(1,3),transform->M(2,3));
+    }
+    if(transform->M(0,0)!=transform->M(1,1) || transform->M(0,0)!=transform->M(2,2))
+    {
+      carttransform->behaviour |= PRC_TRANSFORMATION_NonUniformScale;
+      carttransform->scale.Set(transform->M(0,0),transform->M(1,1),transform->M(2,2));
+    }
+    else
+      if(transform->M(0,0)!=1)
+      {
+        carttransform->behaviour |= PRC_TRANSFORMATION_Scale;
+        carttransform->uniform_scale=transform->M(0,0);
+      }
+    coordinateSystem->axis_set = carttransform;
+  }
+  else
+    coordinateSystem->axis_set = transform;
+
+  const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+  transformMap.insert(make_pair(*transform,coordinate_system_index));
+  if(transform_replaced)
+    delete transform;
+  transform = NULL;
+  return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addTransform(const double* t)
+{
+  if(!t)
+    return m1;
+  PRCGeneralTransformation3d* transform = new PRCGeneralTransformation3d(t);
+  return addTransform(transform);
+}
+
+uint32_t oPRCFile::addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCCartesianTransformation3d* transform = new PRCCartesianTransformation3d(origin, x_axis, y_axis, scale);
+  if(transform->behaviour==PRC_TRANSFORMATION_Identity)
+    return m1;
+  PRCCoordinateSystem *coordinateSystem = new PRCCoordinateSystem();
+  coordinateSystem->axis_set = transform;
+  const uint32_t coordinate_system_index = fileStructures[0]->addCoordinateSystem(coordinateSystem);
+  return coordinate_system_index;
+}
+
+uint32_t oPRCFile::addMaterial(const PRCmaterial& m)
+{
+  uint32_t material_index = m1;
+  const PRCmaterialgeneric materialgeneric(m);
+  PRCmaterialgenericMap::const_iterator pMaterialgeneric = materialgenericMap.find(materialgeneric);
+  if(pMaterialgeneric!=materialgenericMap.end())
+    material_index = pMaterialgeneric->second;
+  else
+  {
+    PRCMaterialGeneric *materialGeneric = new PRCMaterialGeneric();
+    const PRCRgbColor ambient(m.ambient.R, m.ambient.G, m.ambient.B);
+    materialGeneric->ambient = addColor(ambient);
+    const PRCRgbColor diffuse(m.diffuse.R, m.diffuse.G, m.diffuse.B);
+    materialGeneric->diffuse = addColor(diffuse);
+    const PRCRgbColor emissive(m.emissive.R, m.emissive.G, m.emissive.B);
+    materialGeneric->emissive = addColor(emissive);
+    const PRCRgbColor specular(m.specular.R, m.specular.G, m.specular.B);
+    materialGeneric->specular = addColor(specular);
+    materialGeneric->shininess = m.shininess;
+    materialGeneric->ambient_alpha = m.ambient.A;
+    materialGeneric->diffuse_alpha = m.diffuse.A;
+    materialGeneric->emissive_alpha = m.emissive.A;
+    materialGeneric->specular_alpha = m.specular.A;
+    material_index = addMaterialGeneric(materialGeneric);
+    materialgenericMap.insert(make_pair(materialgeneric,material_index));
+  }
+  uint32_t color_material_index = m1;
+  if(m.picture_data!=NULL)
+  {
+    uint32_t picture_index = m1;
+    PRCpicture picture(m);
+    PRCpictureMap::const_iterator pPicture = pictureMap.find(picture);
+    if(pPicture!=pictureMap.end())
+      picture_index = pPicture->second;
+    else
+    {
+      picture_index = addPicture(picture);
+      uint8_t* data = new uint8_t[picture.size];
+      memcpy(data,picture.data,picture.size);
+      picture.data = data;
+      pictureMap.insert(make_pair(picture,picture_index));
+    }
+
+    uint32_t texture_definition_index = m1;
+    PRCtexturedefinition texturedefinition(picture_index, m);
+    PRCtexturedefinitionMap::const_iterator pTexturedefinition = texturedefinitionMap.find(texturedefinition);
+    if(pTexturedefinition!=texturedefinitionMap.end())
+      texture_definition_index = pTexturedefinition->second;
+    else
+    {
+      PRCTextureDefinition *TextureDefinition = new PRCTextureDefinition;
+      TextureDefinition->picture_index = picture_index;
+      TextureDefinition->texture_function = m.picture_replace ? KEPRCTextureFunction_Replace : KEPRCTextureFunction_Modulate;
+      TextureDefinition->texture_wrapping_mode_S = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+      TextureDefinition->texture_wrapping_mode_T = m.picture_repeat ? KEPRCTextureWrappingMode_Repeat : KEPRCTextureWrappingMode_ClampToEdge;
+      TextureDefinition->texture_mapping_attribute_components = m.picture_format==KEPRCPicture_BITMAP_RGB_BYTE ? PRC_TEXTURE_MAPPING_COMPONENTS_RGB : PRC_TEXTURE_MAPPING_COMPONENTS_RGBA;
+      texture_definition_index = addTextureDefinition(TextureDefinition);
+      texturedefinitionMap.insert(make_pair(texturedefinition,texture_definition_index));
+    }
+
+    uint32_t texture_application_index = m1;
+    const PRCtextureapplication textureapplication(material_index, texture_definition_index);
+    PRCtextureapplicationMap::const_iterator pTextureapplication = textureapplicationMap.find(textureapplication);
+    if(pTextureapplication!=textureapplicationMap.end())
+      texture_application_index = pTextureapplication->second;
+    else
+    {
+      PRCTextureApplication *TextureApplication = new PRCTextureApplication;
+      TextureApplication->material_generic_index = material_index;
+      TextureApplication->texture_definition_index = texture_definition_index;
+      texture_application_index = addTextureApplication(TextureApplication);
+      textureapplicationMap.insert(make_pair(textureapplication,texture_application_index));
+    }
+
+    color_material_index = texture_application_index;
+  }
+  else
+    color_material_index = material_index;
+
+  uint32_t style_index = m1;
+  PRCstyle style(0,m.alpha,true,color_material_index);
+  PRCstyleMap::const_iterator pStyle = styleMap.find(style);
+  if(pStyle!=styleMap.end())
+    style_index = pStyle->second;
+  else
+  {
+    PRCStyle *Style = new PRCStyle();
+    Style->line_width = 0.0;
+    Style->is_vpicture = false;
+    Style->line_pattern_vpicture_index = 0;
+    Style->is_material = true;
+    Style->is_transparency_defined = (m.alpha < 1.0);
+    Style->transparency = (uint8_t)(m.alpha * 256);
+    Style->additional = 0;
+    Style->color_material_index = color_material_index;
+    style_index = addStyle(Style);
+    styleMap.insert(make_pair(style,style_index));
+  }
+//  materialMap.insert(make_pair(material,style_index));
+  return style_index;
+}
+
+bool isid(const double* t)
+{
+  return(
+         t[0]==1 && t[4]==0 && t[ 8]==0 && t[12]==0 &&
+         t[1]==0 && t[5]==1 && t[ 9]==0 && t[13]==0 &&
+         t[2]==0 && t[6]==0 && t[10]==1 && t[14]==0 &&
+         t[3]==0 && t[7]==0 && t[11]==0 && t[15]==1 );
+}
+
+
+void oPRCFile::begingroup(const char *name, PRCoptions *options,
+                          const double* t)
+{
+  const PRCgroup &parent_group = groups.top();
+  groups.push(PRCgroup());
+  PRCgroup &group = groups.top();
+  group.name=name;
+  if(options) group.options=*options;
+  if(t&&!isid(t))
+    group.transform = new PRCGeneralTransformation3d(t);
+  group.product_occurrence = new PRCProductOccurrence(name);
+  group.parent_product_occurrence = parent_group.product_occurrence;
+  group.part_definition = new PRCPartDefinition;
+  group.parent_part_definition = parent_group.part_definition;
+}
+
+void oPRCFile::endgroup()
+{
+  if(groups.size()<2) {
+    fputs("begingroup without matching endgroup",stderr);
+    exit(1);
+  }
+  
+  doGroup(groups.top());
+  groups.pop();
+
+// std::cout << lastgroupname << std::endl;
+// for(std::vector<std::string>::const_iterator it=lastgroupnames.begin(); it!=lastgroupnames.end(); it++)
+//   std::cout << " " << *it << std::endl;
+
+}
+
+PRCgroup& oPRCFile::findGroup()
+{
+  return groups.top();
+}
+
+#define ADDWIRE(curvtype)                                 \
+  PRCgroup &group = findGroup();                          \
+  group.wires.push_back(PRCwire());                       \
+  PRCwire &wire = group.wires.back();                     \
+  curvtype *curve = new curvtype;                         \
+  wire.curve = curve;                                     \
+  wire.style = addColour(c);
+
+#define ADDFACE(surftype)                                 \
+  PRCgroup &group = findGroup();                          \
+  group.faces.push_back(PRCface());                       \
+  PRCface& face = group.faces.back();                     \
+  surftype *surface = new surftype;                       \
+  face.face = new PRCFace;                                \
+  face.face->base_surface = surface;                      \
+  face.transparent = m.alpha < 1.0;                       \
+  face.style = addMaterial(m);
+
+#define ADDCOMPFACE                                       \
+  PRCgroup &group = findGroup();                          \
+  group.compfaces.push_back(PRCcompface());               \
+  PRCcompface& face = group.compfaces.back();             \
+  PRCCompressedFace *compface = new PRCCompressedFace;    \
+  face.face = compface;                                   \
+  face.transparent = m.alpha < 1.0;                       \
+  face.style = addMaterial(m);
+
+void oPRCFile::addPoint(const double P[3], const RGBAColour &c, double w)
+{
+  PRCgroup &group = findGroup();
+  group.points[addColourWidth(c,w)].push_back(PRCVector3d(P[0],P[1],P[2]));
+}
+
+void oPRCFile::addPoints(uint32_t n, const double P[][3], const RGBAColour &c, double w)
+{
+  if(n==0 || P==NULL)
+     return;
+  PRCgroup &group = findGroup();
+  PRCPointSet *pointset = new PRCPointSet();
+  group.pointsets.push_back(pointset);
+  pointset->index_of_line_style = addColourWidth(c,w);
+  pointset->point.reserve(n);
+  for(uint32_t i=0; i<n; i++)
+    pointset->point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+  polyBrepModel->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+  polyBrepModel->index_tessellation = tess_index;
+  polyBrepModel->is_closed = group.options.closed;
+  polyBrepModel->index_of_line_style = style_index;
+  group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useMesh(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyBrepModel *polyBrepModel = new PRCPolyBrepModel();
+  polyBrepModel->index_local_coordinate_system = addTransform(t);
+  polyBrepModel->index_tessellation = tess_index;
+  polyBrepModel->is_closed = group.options.closed;
+  polyBrepModel->index_of_line_style = style_index;
+  group.polymodels.push_back(polyBrepModel);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double origin[3], const double x_axis[3], const double y_axis[3], double scale)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyWire *polyWire = new PRCPolyWire();
+  polyWire->index_local_coordinate_system = addTransform(origin, x_axis, y_axis, scale);
+  polyWire->index_tessellation = tess_index;
+  polyWire->index_of_line_style = style_index;
+  group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::useLines(uint32_t tess_index, uint32_t style_index, const double* t)
+{
+  PRCgroup &group = findGroup();
+  PRCPolyWire *polyWire = new PRCPolyWire();
+  polyWire->index_local_coordinate_system = addTransform(t);
+  polyWire->index_tessellation = tess_index;
+  polyWire->index_of_line_style = style_index;
+  group.polywires.push_back(polyWire);
+}
+
+void oPRCFile::addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return;
+  const uint32_t tess_index = createTriangleMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI);
+  useMesh(tess_index,m1);
+}
+
+uint32_t oPRCFile::createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const uint32_t style_index,
+ uint32_t nN, const double N[][3],  const uint32_t NI[][3],
+ uint32_t nT, const double T[][2],  const uint32_t TI[][3],
+ uint32_t nC, const RGBAColour C[], const uint32_t CI[][3],
+ uint32_t nS, const uint32_t S[],   const uint32_t SI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return m1;
+
+  const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+  const bool vertex_color   = (nC != 0 && C != NULL && CI != NULL);
+  const bool has_normals    = (nN != 0 && N != NULL && NI != NULL);
+  const bool textured       = (nT != 0 && T != NULL && TI != NULL);
+
+  PRC3DTess *tess = new PRC3DTess();
+  PRCTessFace *tessFace = new PRCTessFace();
+  tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+  tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  if(has_normals)
+  {
+    tess->normal_coordinate.reserve(3*nN);
+    for(uint32_t i=0; i<nN; i++)
+    {
+      tess->normal_coordinate.push_back(N[i][0]);
+      tess->normal_coordinate.push_back(N[i][1]);
+      tess->normal_coordinate.push_back(N[i][2]);
+    }
+  }
+  if(textured)
+  {
+    tess->texture_coordinate.reserve(2*nT);
+    for(uint32_t i=0; i<nT; i++)
+    {
+      tess->texture_coordinate.push_back(T[i][0]);
+      tess->texture_coordinate.push_back(T[i][1]);
+    }
+  }
+  tess->triangulated_index.reserve(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI);
+  for(uint32_t i=0; i<nI; i++)
+  {
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][0]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][0]);
+    tess->triangulated_index.push_back(3*PI[i][0]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][2]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][2]);
+    tess->triangulated_index.push_back(3*PI[i][2]);
+  }
+  tessFace->sizes_triangulated.push_back(nI);
+  if(triangle_color)
+  {
+    tessFace->line_attributes.reserve(nI);
+    for(uint32_t i=0; i<nI; i++)
+       tessFace->line_attributes.push_back(SI[i]);
+  }
+  else if (style_index != m1 )
+  {
+      tessFace->line_attributes.push_back(style_index);
+  }
+  if(vertex_color)
+  {
+    tessFace->is_rgba=false;
+    for(uint32_t i=0; i<nI; i++)
+      if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+      {
+         tessFace->is_rgba=true;
+         break;
+      }
+
+    tessFace->rgba_vertices.reserve((tessFace->is_rgba?4:3)*3*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+    }
+  }
+  tess->addTessFace(tessFace);
+  const uint32_t tess_index = add3DTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+ uint32_t nM, const PRCmaterial M[], const uint32_t MI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return;
+  const uint32_t tess_index = createQuadMesh(nP, P, nI, PI, m, nN, N, NI, nT, T, TI, nC, C, CI, nM, M, MI);
+  useMesh(tess_index,m1);
+}
+
+uint32_t oPRCFile::createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+ uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+ uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+ uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+ uint32_t nS, const uint32_t S[],    const uint32_t SI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+     return m1;
+
+  const bool triangle_color = (nS != 0 && S != NULL && SI != NULL);
+  const bool vertex_color   = (nC != 0 && C != NULL && CI != NULL);
+  const bool has_normals    = (nN != 0 && N != NULL && NI != NULL);
+  const bool textured       = (nT != 0 && T != NULL && TI != NULL);
+
+  PRC3DTess *tess = new PRC3DTess();
+  PRCTessFace *tessFace = new PRCTessFace();
+  tessFace->used_entities_flag = textured ? PRC_FACETESSDATA_TriangleTextured : PRC_FACETESSDATA_Triangle;
+  tessFace->number_of_texture_coordinate_indexes = textured ? 1 : 0;
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  if(has_normals)
+  {
+    tess->normal_coordinate.reserve(3*nN);
+    for(uint32_t i=0; i<nN; i++)
+    {
+      tess->normal_coordinate.push_back(N[i][0]);
+      tess->normal_coordinate.push_back(N[i][1]);
+      tess->normal_coordinate.push_back(N[i][2]);
+    }
+  }
+  if(textured)
+  {
+    tess->texture_coordinate.reserve(2*nT);
+    for(uint32_t i=0; i<nT; i++)
+    {
+      tess->texture_coordinate.push_back(T[i][0]);
+      tess->texture_coordinate.push_back(T[i][1]);
+    }
+  }
+  tess->triangulated_index.reserve(2*(3*nI+(has_normals?3:0)*nI+(textured?3:0)*nI));
+  for(uint32_t i=0; i<nI; i++)
+  {
+    // first triangle
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][0]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][0]);
+    tess->triangulated_index.push_back(3*PI[i][0]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][3]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][3]);
+    tess->triangulated_index.push_back(3*PI[i][3]);
+    // second triangle
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][1]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][1]);
+    tess->triangulated_index.push_back(3*PI[i][1]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][2]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][2]);
+    tess->triangulated_index.push_back(3*PI[i][2]);
+    if(has_normals)
+    tess->triangulated_index.push_back(3*NI[i][3]);
+    if(textured)
+    tess->triangulated_index.push_back(2*TI[i][3]);
+    tess->triangulated_index.push_back(3*PI[i][3]);
+  }
+  tessFace->sizes_triangulated.push_back(2*nI);
+  if(triangle_color)
+  {
+    tessFace->line_attributes.reserve(2*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       tessFace->line_attributes.push_back(SI[i]);
+       tessFace->line_attributes.push_back(SI[i]);
+    }
+  }
+  else
+  {
+      tessFace->line_attributes.push_back(style_index);
+  }
+  if(vertex_color)
+  {
+    tessFace->is_rgba=false;
+    for(uint32_t i=0; i<nI; i++)
+      if(1.0 != C[CI[i][0]].A || 1.0 != C[CI[i][1]].A || 1.0 != C[CI[i][2]].A)
+      {
+         tessFace->is_rgba=true;
+         break;
+      }
+
+    tessFace->rgba_vertices.reserve(2*(tessFace->is_rgba?4:3)*3*nI);
+    for(uint32_t i=0; i<nI; i++)
+    {
+       // first triangle
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][0]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+       // second triangle
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][1]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][2]].A));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].R));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].G));
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].B));
+       if(tessFace->is_rgba)
+       tessFace->rgba_vertices.push_back(byte(C[CI[i][3]].A));
+    }
+  }
+  tess->addTessFace(tessFace);
+  const uint32_t tess_index = add3DTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addQuad(const double P[][3], const RGBAColour C[])
+{
+  PRCgroup &group = findGroup();
+  
+  group.quads.push_back(PRCtessquad());
+  PRCtessquad &quad = group.quads.back();
+  for(size_t i = 0; i < 4; i++)
+  {
+    quad.vertices[i].x = P[i][0];
+    quad.vertices[i].y = P[i][1];
+    quad.vertices[i].z = P[i][2];
+    quad.colours[i] = C[i];
+  }
+}
+/*
+void oPRCFile::addTriangle(const double P[][3], const double T[][2], uint32_t style_index)
+{
+  PRCgroup &group = findGroup();
+  
+  group.triangles.push_back(PRCtesstriangle());
+  PRCtesstriangle &triangle = group.triangles.back();
+  for(size_t i = 0; i < 3; i++)
+  {
+    triangle.vertices[i].x = P[i][0];
+    triangle.vertices[i].y = P[i][1];
+    triangle.vertices[i].z = P[i][2];
+    triangle.texcoords[i].x = T[i][0];
+    triangle.texcoords[i].y = T[i][1];
+  }
+  triangle.style = style_index;
+}
+*/
+
+void oPRCFile::addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ const RGBAColour& c, double w,
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+    return;
+  const uint32_t tess_index = createLines(nP, P, nI, PI, segment_color, nC, C, nCI, CI);
+  useLines(tess_index, c, w);
+}
+
+uint32_t oPRCFile::createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+ bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[])
+{
+  if(nP==0 || P==NULL || nI==0 || PI==NULL)
+    return m1;
+
+  const bool vertex_color  = (nC != 0 && C != NULL && CI != NULL);
+
+  PRC3DWireTess *tess = new PRC3DWireTess();
+  tess->coordinates.reserve(3*nP);
+  for(uint32_t i=0; i<nP; i++)
+  {
+    tess->coordinates.push_back(P[i][0]);
+    tess->coordinates.push_back(P[i][1]);
+    tess->coordinates.push_back(P[i][2]);
+  }
+  tess->wire_indexes.reserve(nI);
+  for(uint32_t i=0; i<nI;)
+  {
+    tess->wire_indexes.push_back(PI[i]);
+    const uint32_t ni = i+PI[i]+1;
+    for(i++; i<ni; i++)
+      tess->wire_indexes.push_back(3*PI[i]);
+  }
+  if(vertex_color)
+  {
+    tess->is_segment_color = segment_color;
+    tess->is_rgba=false;
+    for(uint32_t i=0; i<nCI; i++)
+      if(1.0 != C[CI[i]].A)
+      {
+         tess->is_rgba=true;
+         break;
+      }
+    tess->rgba_vertices.reserve((tess->is_rgba?4:3)*nCI);
+    for(uint32_t i=0; i<nCI; i++)
+    {
+       tess->rgba_vertices.push_back(byte(C[CI[i]].R));
+       tess->rgba_vertices.push_back(byte(C[CI[i]].G));
+       tess->rgba_vertices.push_back(byte(C[CI[i]].B));
+       if(tess->is_rgba)
+       tess->rgba_vertices.push_back(byte(C[CI[i]].A));
+    }
+  }
+  const uint32_t tess_index = add3DWireTess(tess);
+  return tess_index;
+}
+
+void oPRCFile::addLine(uint32_t n, const double P[][3], const RGBAColour &c, double w)
+{
+  PRCgroup &group = findGroup();
+  if(group.options.tess)
+  {
+    group.lines[w].push_back(PRCtessline());
+    PRCtessline& line = group.lines[w].back();
+    line.color.red   = c.R;
+    line.color.green = c.G;
+    line.color.blue  = c.B;
+    for(uint32_t i=0; i<n; i++)
+      line.point.push_back(PRCVector3d(P[i][0],P[i][1],P[i][2]));
+  }
+  else
+  {
+    ADDWIRE(PRCPolyLine)
+    curve->point.resize(n);
+    for(uint32_t i=0; i<n; i++)
+     curve->point[i].Set(P[i][0],P[i][1],P[i][2]);
+    curve->interval.min = 0;
+    curve->interval.max = curve->point.size()-1;
+  }
+}
+
+void oPRCFile::addBezierCurve(uint32_t n, const double cP[][3],
+                              const RGBAColour &c)
+{
+  ADDWIRE(PRCNURBSCurve)
+  curve->is_rational = false;
+  curve->degree = 3;
+  const size_t NUMBER_OF_POINTS = n;
+  curve->control_point.resize(NUMBER_OF_POINTS);
+  for(size_t i = 0; i < NUMBER_OF_POINTS; ++i)
+    curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+  curve->knot.resize(3+NUMBER_OF_POINTS+1);
+  curve->knot[0] = 1;
+  for(size_t i = 1; i < 3+NUMBER_OF_POINTS; ++i)
+    curve->knot[i] = (i+2)/3; // integer division is intentional
+  curve->knot[3+NUMBER_OF_POINTS] = (3+NUMBER_OF_POINTS+1)/3;
+}
+
+void oPRCFile::addCurve(uint32_t d, uint32_t n, const double cP[][3], const double *k, const RGBAColour &c, const double w[])
+{
+  ADDWIRE(PRCNURBSCurve)
+  curve->is_rational = (w!=NULL);
+  curve->degree = d;
+  curve->control_point.resize(n);
+  for(uint32_t i = 0; i < n; i++)
+    if(w)
+      curve->control_point[i].Set(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]);
+    else
+      curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+  curve->knot.resize(d+n+1);
+  for(uint32_t i = 0; i < d+n+1; i++)
+    curve->knot[i] = k[i];
+}
+
+void oPRCFile::addRectangle(const double P[][3], const PRCmaterial &m)
+{
+  PRCgroup &group = findGroup();
+  if(group.options.tess)
+  {
+    group.rectangles.push_back(PRCtessrectangle());
+    PRCtessrectangle &rectangle = group.rectangles.back();
+    rectangle.style = addMaterial(m);
+    for(size_t i = 0; i < 4; i++)
+    {
+       rectangle.vertices[i].x = P[i][0];
+       rectangle.vertices[i].y = P[i][1];
+       rectangle.vertices[i].z = P[i][2];
+    }
+  }
+  else if(group.options.compression == 0.0)
+  {
+    ADDFACE(PRCNURBSSurface)
+
+    surface->is_rational = false;
+    surface->degree_in_u = 1;
+    surface->degree_in_v = 1;
+    surface->control_point.resize(4);
+    for(size_t i = 0; i < 4; ++i)
+    {
+        surface->control_point[i].x = P[i][0];
+        surface->control_point[i].y = P[i][1];
+        surface->control_point[i].z = P[i][2];
+    }
+    surface->knot_u.resize(4);
+    surface->knot_v.resize(4);
+    surface->knot_v[0] = surface->knot_u[0] = 1;
+    surface->knot_v[1] = surface->knot_u[1] = 3;
+    surface->knot_v[2] = surface->knot_u[2] = 4;
+    surface->knot_v[3] = surface->knot_u[3] = 4;
+  }
+  else
+  {
+    ADDCOMPFACE
+
+    compface->degree = 1;
+    compface->control_point.resize(4);
+    for(size_t i = 0; i < 4; ++i)
+    {
+        compface->control_point[i].x = P[i][0];
+        compface->control_point[i].y = P[i][1];
+        compface->control_point[i].z = P[i][2];
+    }
+  }
+}
+
+void oPRCFile::addPatch(const double cP[][3], const PRCmaterial &m)
+{
+  PRCgroup &group = findGroup();
+  if(group.options.compression == 0.0)
+  {
+    ADDFACE(PRCNURBSSurface)
+
+    surface->is_rational = false;
+    surface->degree_in_u = 3;
+    surface->degree_in_v = 3;
+    surface->control_point.resize(16);
+    for(size_t i = 0; i < 16; ++i)
+    {
+        surface->control_point[i].x = cP[i][0];
+        surface->control_point[i].y = cP[i][1];
+        surface->control_point[i].z = cP[i][2];
+    }
+    surface->knot_u.resize(8);
+    surface->knot_v.resize(8);
+    surface->knot_v[0] = surface->knot_u[0] = 1;
+    surface->knot_v[1] = surface->knot_u[1] = 1;
+    surface->knot_v[2] = surface->knot_u[2] = 1;
+    surface->knot_v[3] = surface->knot_u[3] = 1;
+    surface->knot_v[4] = surface->knot_u[4] = 2;
+    surface->knot_v[5] = surface->knot_u[5] = 2;
+    surface->knot_v[6] = surface->knot_u[6] = 2;
+    surface->knot_v[7] = surface->knot_u[7] = 2;
+  }
+  else
+  {
+    ADDCOMPFACE
+
+    compface->degree = 3;
+    compface->control_point.resize(16);
+    for(size_t i = 0; i < 16; ++i)
+    {
+        compface->control_point[i].x = cP[i][0];
+        compface->control_point[i].y = cP[i][1];
+        compface->control_point[i].z = cP[i][2];
+    }
+  }
+}
+
+void oPRCFile::addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+                          const double cP[][3], const double *kU,
+                          const double *kV, const PRCmaterial &m,
+                          const double w[])
+{
+  ADDFACE(PRCNURBSSurface)
+
+  surface->is_rational = (w!=NULL);
+  surface->degree_in_u = dU;
+  surface->degree_in_v = dV;
+  surface->control_point.resize(nU*nV);
+  for(size_t i = 0; i < nU*nV; i++)
+    if(w)
+      surface->control_point[i]=PRCControlPoint(cP[i][0]*w[i],cP[i][1]*w[i],cP[i][2]*w[i],w[i]);
+    else
+      surface->control_point[i]=PRCControlPoint(cP[i][0],cP[i][1],cP[i][2]);
+  surface->knot_u.insert(surface->knot_u.end(), kU, kU+(dU+nU+1));
+  surface->knot_v.insert(surface->knot_v.end(), kV, kV+(dV+nV+1));
+}
+
+#define SETTRANSF \
+  if(t&&!isid(t))                                                             \
+    face.transform = new PRCGeneralTransformation3d(t);                       \
+  if(origin) surface->origin.Set(origin[0],origin[1],origin[2]);              \
+  if(x_axis) surface->x_axis.Set(x_axis[0],x_axis[1],x_axis[2]);              \
+  if(y_axis) surface->y_axis.Set(y_axis[0],y_axis[1],y_axis[2]);              \
+  surface->scale = scale;                                                     \
+  surface->geometry_is_2D = false;                                            \
+  if(surface->origin!=PRCVector3d(0.0,0.0,0.0))                                     \
+    surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Translate;   \
+  if(surface->x_axis!=PRCVector3d(1.0,0.0,0.0)||surface->y_axis!=PRCVector3d(0.0,1.0,0.0)) \
+    surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Rotate;      \
+  if(surface->scale!=1)                                                       \
+    surface->behaviour = surface->behaviour | PRC_TRANSFORMATION_Scale;       \
+  surface->has_transformation = (surface->behaviour != PRC_TRANSFORMATION_Identity);
+
+#define PRCFACETRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale, const double* t
+
+void oPRCFile::addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCBlend01)
+  SETTRANSF
+  if(straight)
+  {
+    PRCPolyLine *center_curve = new PRCPolyLine;
+    center_curve->point.resize(n);
+    for(uint32_t i=0; i<n; i++)
+      center_curve->point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+    center_curve->interval.min = 0;
+    center_curve->interval.max = center_curve->point.size()-1;
+    surface->center_curve = center_curve;
+
+    PRCPolyLine *origin_curve = new PRCPolyLine;
+    origin_curve->point.resize(n);
+    for(uint32_t i=0; i<n; i++)
+      origin_curve->point[i].Set(oP[i][0],oP[i][1],oP[i][2]);
+    origin_curve->interval.min = 0;
+    origin_curve->interval.max = origin_curve->point.size()-1;
+    surface->origin_curve = origin_curve;
+
+    surface->uv_domain.min.x = 0;
+    surface->uv_domain.max.x = 2*pi;
+    surface->uv_domain.min.y = 0;
+    surface->uv_domain.max.y = n-1;
+  }
+  else
+  {
+    PRCNURBSCurve *center_curve = new PRCNURBSCurve;
+    center_curve->is_rational = false;
+    center_curve->degree = 3;
+    const uint32_t CENTER_NUMBER_OF_POINTS = n;
+    center_curve->control_point.resize(CENTER_NUMBER_OF_POINTS);
+    for(uint32_t i = 0; i < CENTER_NUMBER_OF_POINTS; ++i)
+      center_curve->control_point[i].Set(cP[i][0],cP[i][1],cP[i][2]);
+    center_curve->knot.resize(3+CENTER_NUMBER_OF_POINTS+1);
+    center_curve->knot[0] = 1;
+    for(uint32_t i = 1; i < 3+CENTER_NUMBER_OF_POINTS; ++i)
+      center_curve->knot[i] = (i+2)/3; // integer division is intentional
+    center_curve->knot[3+CENTER_NUMBER_OF_POINTS] = (3+CENTER_NUMBER_OF_POINTS+1)/3;
+    surface->center_curve = center_curve;
+
+    PRCNURBSCurve *origin_curve = new PRCNURBSCurve;
+    origin_curve->is_rational = false;
+    origin_curve->degree = 3;
+    const uint32_t ORIGIN_NUMBER_OF_POINTS = n;
+    origin_curve->control_point.resize(ORIGIN_NUMBER_OF_POINTS);
+    for(uint32_t i = 0; i < ORIGIN_NUMBER_OF_POINTS; ++i)
+      origin_curve->control_point[i].Set(oP[i][0],oP[i][1],oP[i][2]);
+    origin_curve->knot.resize(3+ORIGIN_NUMBER_OF_POINTS+1);
+    origin_curve->knot[0] = 1;
+    for(size_t i = 1; i < 3+ORIGIN_NUMBER_OF_POINTS; ++i)
+      origin_curve->knot[i] = (i+2)/3; // integer division is intentional
+    origin_curve->knot[3+ORIGIN_NUMBER_OF_POINTS] = (3+ORIGIN_NUMBER_OF_POINTS+1)/3;
+    surface->origin_curve = origin_curve;
+
+    surface->uv_domain.min.x = 0;
+    surface->uv_domain.max.x = 2*pi;
+    surface->uv_domain.min.y = 1; // first knot
+    surface->uv_domain.max.y = (3+CENTER_NUMBER_OF_POINTS+1)/3; // last knot
+  }
+}
+
+void oPRCFile::addHemisphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCSphere)
+  SETTRANSF
+  surface->uv_domain.min.x = 0;
+  surface->uv_domain.max.x = 2*pi;
+  surface->uv_domain.min.y = 0;
+  surface->uv_domain.max.y = 0.5*pi;
+  surface->radius = radius;
+}
+
+void oPRCFile::addSphere(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCSphere)
+  SETTRANSF
+  surface->uv_domain.min.x = 0;
+  surface->uv_domain.max.x = 2*pi;
+  surface->uv_domain.min.y =-0.5*pi;
+  surface->uv_domain.max.y = 0.5*pi;
+  surface->radius = radius;
+}
+
+void oPRCFile::addDisk(double radius, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCRuled)
+  SETTRANSF
+  PRCCircle *first_curve = new PRCCircle;
+  first_curve->radius = radius;
+  surface->first_curve = first_curve;
+  PRCCircle *second_curve = new PRCCircle;
+  second_curve->radius = 0;
+  surface->second_curve = second_curve;
+
+  surface->uv_domain.min.x = 0;
+  surface->uv_domain.max.x = 1;
+  surface->uv_domain.min.y = 0;
+  surface->uv_domain.max.y = 2*pi;
+  surface->parameterization_on_v_coeff_a = -1;
+  surface->parameterization_on_v_coeff_b = 2*pi;
+}
+
+void oPRCFile::addCylinder(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCCylinder)
+  SETTRANSF
+  surface->uv_domain.min.x = 0;
+  surface->uv_domain.max.x = 2*pi;
+  surface->uv_domain.min.y = (height>0)?0:height;
+  surface->uv_domain.max.y = (height>0)?height:0;
+  surface->radius = radius;
+}
+
+void oPRCFile::addCone(double radius, double height, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCCone)
+  SETTRANSF
+  surface->uv_domain.min.x = 0;
+  surface->uv_domain.max.x = 2*pi;
+  surface->uv_domain.min.y = (height>0)?0:height;
+  surface->uv_domain.max.y = (height>0)?height:0;
+  surface->bottom_radius = radius;
+  surface->semi_angle = -atan(radius/height);;
+}
+
+void oPRCFile::addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial &m, PRCFACETRANSFORM)
+{
+  ADDFACE(PRCTorus)
+  SETTRANSF
+  surface->uv_domain.min.x = (angle1/180)*pi;
+  surface->uv_domain.max.x = (angle2/180)*pi;
+  surface->uv_domain.min.y = 0;
+  surface->uv_domain.max.y = 2*pi;
+  surface->major_radius = major_radius;
+  surface->minor_radius = minor_radius;
+}
+
+#undef PRCFACETRANSFORM
+#undef ADDFACE
+#undef ADDWIRE
+#undef SETTRANSF
+
+uint32_t PRCFileStructure::addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric)
+{
+  materials.push_back(pMaterialGeneric);
+  pMaterialGeneric = NULL;
+  return materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addTextureApplication(PRCTextureApplication*& pTextureApplication)
+{
+  materials.push_back(pTextureApplication);
+  pTextureApplication = NULL;
+  return materials.size()-1;
+}
+
+uint32_t PRCFileStructure::addStyle(PRCStyle*& pStyle)
+{
+  styles.push_back(pStyle);
+  pStyle = NULL;
+  return styles.size()-1;
+}
+
+uint32_t PRCFileStructure::addPartDefinition(PRCPartDefinition*& pPartDefinition)
+{
+  part_definitions.push_back(pPartDefinition);
+  pPartDefinition = NULL;
+  return part_definitions.size()-1;
+}
+
+uint32_t PRCFileStructure::addProductOccurrence(PRCProductOccurrence*& pProductOccurrence)
+{
+  product_occurrences.push_back(pProductOccurrence);
+  pProductOccurrence = NULL;
+  return product_occurrences.size()-1;
+}
+
+uint32_t PRCFileStructure::addTopoContext(PRCTopoContext*& pTopoContext)
+{
+  contexts.push_back(pTopoContext);
+  pTopoContext = NULL;
+  return contexts.size()-1;
+}
+
+uint32_t PRCFileStructure::getTopoContext(PRCTopoContext*& pTopoContext)
+{
+  pTopoContext = new PRCTopoContext;
+  contexts.push_back(pTopoContext);
+  return contexts.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DTess(PRC3DTess*& p3DTess)
+{
+  tessellations.push_back(p3DTess);
+  p3DTess = NULL;
+  return tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::add3DWireTess(PRC3DWireTess*& p3DWireTess)
+{
+  tessellations.push_back(p3DWireTess);
+  p3DWireTess = NULL;
+  return tessellations.size()-1;
+}
+/*
+uint32_t PRCFileStructure::addMarkupTess(PRCMarkupTess*& pMarkupTess)
+{
+  tessellations.push_back(pMarkupTess);
+  pMarkupTess = NULL;
+  return tessellations.size()-1;
+}
+
+uint32_t PRCFileStructure::addMarkup(PRCMarkup*& pMarkup)
+{
+  markups.push_back(pMarkup);
+  pMarkup = NULL;
+  return markups.size()-1;
+}
+
+uint32_t PRCFileStructure::addAnnotationItem(PRCAnnotationItem*& pAnnotationItem)
+{
+  annotation_entities.push_back(pAnnotationItem);
+  pAnnotationItem = NULL;
+  return annotation_entities.size()-1;
+}
+*/
+uint32_t PRCFileStructure::addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem)
+{
+  reference_coordinate_systems.push_back(pCoordinateSystem);
+  pCoordinateSystem = NULL;
+  return reference_coordinate_systems.size()-1;
+}
+
+uint32_t PRCFileStructure::addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem)
+{
+  for(uint32_t i = 0; i < reference_coordinate_systems.size(); ++i)
+  {
+    if(*(reference_coordinate_systems[i])==*pCoordinateSystem) {
+      pCoordinateSystem = NULL;
+      return i;
+    }
+  }
+  reference_coordinate_systems.push_back(pCoordinateSystem);
+  pCoordinateSystem = NULL;
+  return reference_coordinate_systems.size()-1;
+}
diff --git a/src/prc/oPRCFile.h b/src/prc/oPRCFile.h
new file mode 100644 (file)
index 0000000..25906ff
--- /dev/null
@@ -0,0 +1,926 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __O_PRC_FILE_H
+#define __O_PRC_FILE_H
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+#include <stack>
+#include <string>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "PRC.h"
+#include "PRCbitStream.h"
+#include "writePRC.h"
+
+class oPRCFile;
+class PRCFileStructure;
+
+struct RGBAColour
+{
+  RGBAColour(double r=0.0, double g=0.0, double b=0.0, double a=1.0) :
+    R(r), G(g), B(b), A(a) {}
+  double R,G,B,A;
+
+  void Set(double r, double g, double b, double a=1.0) 
+  {
+    R = r; G = g; B = b; A = a;
+  }
+  bool operator==(const RGBAColour& c) const
+  {
+    return (R==c.R && G==c.G && B==c.B && A==c.A);
+  }
+  bool operator!=(const RGBAColour& c) const
+  {
+    return !(R==c.R && G==c.G && B==c.B && A==c.A);
+  }
+  bool operator<(const RGBAColour& c) const
+  {
+    if(R!=c.R)
+      return (R<c.R);
+    if(G!=c.G)
+      return (G<c.G);
+    if(B!=c.B)
+      return (B<c.B);
+    return (A<c.A);
+  }
+  friend RGBAColour operator * (const RGBAColour& a, const double d)
+  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+  friend RGBAColour operator * (const double d, const RGBAColour& a)
+  { return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+
+};
+typedef std::map<RGBAColour,uint32_t> PRCcolourMap;
+
+struct RGBAColourWidth
+{
+  RGBAColourWidth(double r=0.0, double g=0.0, double b=0.0, double a=1.0, double w=1.0) :
+    R(r), G(g), B(b), A(a), W(w) {}
+  double R,G,B,A,W;
+
+  bool operator==(const RGBAColourWidth& c) const
+  {
+    return (R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+  }
+  bool operator!=(const RGBAColourWidth& c) const
+  {
+    return !(R==c.R && G==c.G && B==c.B && A==c.A && W==c.W);
+  }
+  bool operator<(const RGBAColourWidth& c) const
+  {
+    if(R!=c.R)
+      return (R<c.R);
+    if(G!=c.G)
+      return (G<c.G);
+    if(B!=c.B)
+      return (B<c.B);
+    if(A!=c.A)
+      return (A<c.A);
+    return (W<c.W);
+  }
+};
+typedef std::map<RGBAColourWidth,uint32_t> PRCcolourwidthMap;
+
+typedef std::map<PRCRgbColor,uint32_t> PRCcolorMap;
+
+struct PRCmaterial
+{
+  PRCmaterial() : alpha(1.0),shininess(1.0),
+      picture_data(NULL), picture_format(KEPRCPicture_BITMAP_RGB_BYTE), picture_width(0), picture_height(0), picture_size(0),
+      picture_replace(false), picture_repeat(false) {}
+  PRCmaterial(const RGBAColour& a, const RGBAColour& d, const RGBAColour& e,
+              const RGBAColour& s, double p, double h,
+              const uint8_t* pic=NULL, EPRCPictureDataFormat picf=KEPRCPicture_BITMAP_RGB_BYTE,
+              uint32_t picw=0, uint32_t pich=0, uint32_t pics=0, bool picreplace=false, bool picrepeat=false) :
+      ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h),
+      picture_data(pic), picture_format(picf), picture_width(picw), picture_height(pich), picture_size(pics),
+      picture_replace(picreplace), picture_repeat(picrepeat) {
+        if(picture_size==0)
+        {
+          if (picture_format==KEPRCPicture_BITMAP_RGB_BYTE)
+             picture_size = picture_width*picture_height*3;
+          if (picture_format==KEPRCPicture_BITMAP_RGBA_BYTE)
+             picture_size = picture_width*picture_height*4;
+          if (picture_format==KEPRCPicture_BITMAP_GREY_BYTE)
+             picture_size = picture_width*picture_height*1;
+          if (picture_format==KEPRCPicture_BITMAP_GREYA_BYTE)
+             picture_size = picture_width*picture_height*2;
+        }
+      }
+  RGBAColour ambient,diffuse,emissive,specular;
+  double alpha,shininess;
+  const uint8_t* picture_data;
+  EPRCPictureDataFormat picture_format;
+  uint32_t picture_width;
+  uint32_t picture_height;
+  uint32_t picture_size;
+  bool picture_replace; // replace material color with texture color? if false - just modify
+  bool picture_repeat;  // repeat texture? if false - clamp to edge
+
+  bool operator==(const PRCmaterial& m) const
+  {
+    return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+        && specular==m.specular && alpha==m.alpha && shininess==m.shininess
+        && picture_replace==m.picture_replace && picture_repeat==m.picture_repeat
+        && picture_format==m.picture_format
+        && picture_width==m.picture_width && picture_height==m.picture_height && picture_size==m.picture_size
+        && (picture_data==m.picture_data || memcmp(picture_data,m.picture_data,picture_size)==0) );
+  }
+  bool operator<(const PRCmaterial& m) const
+  {
+    if(ambient!=m.ambient)
+      return (ambient<m.ambient);
+    if(diffuse!=m.diffuse)
+      return (diffuse<m.diffuse);
+    if(emissive!=m.emissive)
+      return (emissive<m.emissive);
+    if(specular!=m.specular)
+      return (specular<m.specular);
+    if(alpha!=m.alpha)
+      return (alpha<m.alpha);
+    if(shininess!=m.shininess)
+      return (shininess<m.shininess);
+    if(picture_replace!=m.picture_replace)
+      return (picture_replace<m.picture_replace);
+    if(picture_repeat!=m.picture_repeat)
+      return (picture_repeat<m.picture_repeat);
+    if(picture_format!=m.picture_format)
+      return (picture_format<m.picture_format);
+    if(picture_width!=m.picture_width)
+      return (picture_width<m.picture_width);
+    if(picture_height!=m.picture_height)
+      return (picture_height<m.picture_height);
+    if(picture_size!=m.picture_size)
+      return (picture_size<m.picture_size);
+    if(picture_data!=m.picture_data)
+      return (memcmp(picture_data,m.picture_data,picture_size)<0);
+    return false;
+  }
+};
+typedef std::map<PRCmaterial,uint32_t> PRCmaterialMap;
+
+struct PRCpicture
+{
+  PRCpicture() : 
+      data(NULL), format(KEPRCPicture_BITMAP_RGB_BYTE),
+      width(0), height(0), size(0) {}
+  PRCpicture(const uint8_t* pic, EPRCPictureDataFormat picf,
+             uint32_t picw, uint32_t pich, uint32_t pics=0) :
+      data(pic), format(picf),
+      width(picw), height(pich), size(pics)
+  {
+    if(size==0)
+    {
+      if (format==KEPRCPicture_BITMAP_RGB_BYTE)
+         size = width*height*3;
+      if (format==KEPRCPicture_BITMAP_RGBA_BYTE)
+         size = width*height*4;
+      if (format==KEPRCPicture_BITMAP_GREY_BYTE)
+         size = width*height*1;
+      if (format==KEPRCPicture_BITMAP_GREYA_BYTE)
+         size = width*height*2;
+    }
+  }
+  PRCpicture(const PRCmaterial& m) :
+      data(m.picture_data), format(m.picture_format),
+      width(m.picture_width), height(m.picture_height), size(m.picture_size) {}
+
+  const uint8_t* data;
+  EPRCPictureDataFormat format;
+  uint32_t width;
+  uint32_t height;
+  uint32_t size;
+  bool operator==(const PRCpicture& p) const
+  {
+    return ( format==p.format
+        && width==p.width && height==p.height && size==p.size
+        && (data==p.data || memcmp(data,p.data,size)==0) );
+  }
+  bool operator<(const PRCpicture& p) const
+  {
+    if(format!=p.format)
+      return (format<p.format);
+    if(width!=p.width)
+      return (width<p.width);
+    if(height!=p.height)
+      return (height<p.height);
+    if(size!=p.size)
+      return (size<p.size);
+    if(data!=p.data)
+      return (memcmp(data,p.data,size)<0);
+    return false;
+  }
+};
+
+typedef std::map<PRCpicture,uint32_t> PRCpictureMap;
+
+struct PRCmaterialgeneric
+{
+  PRCmaterialgeneric() : alpha(1.0),shininess(1.0) {}
+  PRCmaterialgeneric(const RGBAColour& a, const RGBAColour& d, const RGBAColour& e,
+              const RGBAColour& s, double p, double h) :
+      ambient(a), diffuse(d), emissive(e), specular(s), alpha(p), shininess(h) {}
+  PRCmaterialgeneric(const PRCmaterial& m) :
+      ambient(m.ambient), diffuse(m.diffuse), emissive(m.emissive), specular(m.specular), alpha(m.alpha), shininess(m.shininess) {}
+  RGBAColour ambient,diffuse,emissive,specular;
+  double alpha,shininess;
+
+  bool operator==(const PRCmaterialgeneric& m) const
+  {
+    return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive
+        && specular==m.specular && alpha==m.alpha && shininess==m.shininess);
+  }
+  bool operator<(const PRCmaterialgeneric& m) const
+  {
+    if(ambient!=m.ambient)
+      return (ambient<m.ambient);
+    if(diffuse!=m.diffuse)
+      return (diffuse<m.diffuse);
+    if(emissive!=m.emissive)
+      return (emissive<m.emissive);
+    if(specular!=m.specular)
+      return (specular<m.specular);
+    if(alpha!=m.alpha)
+      return (alpha<m.alpha);
+    if(shininess!=m.shininess)
+      return (shininess<m.shininess);
+    return false;
+  }
+};
+typedef std::map<PRCmaterialgeneric,uint32_t> PRCmaterialgenericMap;
+
+struct PRCtexturedefinition
+{
+  PRCtexturedefinition() : 
+      picture_index(m1), picture_replace(false), picture_repeat(false) {}
+  PRCtexturedefinition(uint32_t picindex, bool picreplace=false, bool picrepeat=false) :
+      picture_index(picindex), picture_replace(picreplace), picture_repeat(picrepeat) {}
+  PRCtexturedefinition(uint32_t picindex, const PRCmaterial& m) :
+      picture_index(picindex), picture_replace(m.picture_replace), picture_repeat(m.picture_repeat) {}
+  uint32_t picture_index;
+  bool picture_replace; // replace material color with texture color? if false - just modify
+  bool picture_repeat;  // repeat texture? if false - clamp to edge
+
+  bool operator==(const PRCtexturedefinition& t) const
+  {
+    return (picture_index==t.picture_index
+        && picture_replace==t.picture_replace && picture_repeat==t.picture_repeat);
+  }
+  bool operator<(const PRCtexturedefinition& t) const
+  {
+    if(picture_index!=t.picture_index)
+      return (picture_index<t.picture_index);
+    if(picture_replace!=t.picture_replace)
+      return (picture_replace<t.picture_replace);
+    if(picture_repeat!=t.picture_repeat)
+      return (picture_repeat<t.picture_repeat);
+    return false;
+  }
+};
+typedef std::map<PRCtexturedefinition,uint32_t> PRCtexturedefinitionMap;
+
+struct PRCtextureapplication
+{
+  PRCtextureapplication() : 
+      material_generic_index(m1), texture_definition_index(m1) {}
+  PRCtextureapplication(uint32_t matindex, uint32_t texindex) :
+      material_generic_index(matindex), texture_definition_index(texindex) {}
+  uint32_t material_generic_index;
+  uint32_t texture_definition_index;
+
+  bool operator==(const PRCtextureapplication& t) const
+  {
+    return (material_generic_index==t.material_generic_index
+        && texture_definition_index==t.texture_definition_index);
+  }
+  bool operator<(const PRCtextureapplication& t) const
+  {
+    if(material_generic_index!=t.material_generic_index)
+      return (material_generic_index<t.material_generic_index);
+    if(texture_definition_index!=t.texture_definition_index)
+      return (texture_definition_index<t.texture_definition_index);
+    return false;
+  }
+};
+typedef std::map<PRCtextureapplication,uint32_t> PRCtextureapplicationMap;
+
+struct PRCstyle
+{
+  PRCstyle() : 
+      line_width(0), alpha(1), is_material(false), color_material_index(m1) {}
+  PRCstyle(double linewidth, double alph, bool ismat, uint32_t colindex=m1) :
+      line_width(linewidth), alpha(alph), is_material(ismat), color_material_index(colindex) {}
+  double line_width;
+  double alpha;
+  bool is_material;
+  uint32_t color_material_index;
+
+  bool operator==(const PRCstyle& s) const
+  {
+    return (line_width==s.line_width && alpha==s.alpha && is_material==s.is_material
+        && color_material_index==s.color_material_index);
+  }
+  bool operator<(const PRCstyle& s) const
+  {
+    if(line_width!=s.line_width)
+      return (line_width<s.line_width);
+    if(alpha!=s.alpha)
+      return (alpha<s.alpha);
+    if(is_material!=s.is_material)
+      return (is_material<s.is_material);
+    if(color_material_index!=s.color_material_index)
+      return (color_material_index<s.color_material_index);
+    return false;
+  }
+};
+typedef std::map<PRCstyle,uint32_t> PRCstyleMap;
+
+struct PRCtessrectangle // rectangle
+{
+  PRCVector3d vertices[4];
+  uint32_t style;
+};
+typedef std::vector<PRCtessrectangle> PRCtessrectangleList;
+
+struct PRCtessquad // rectangle
+{
+  PRCVector3d vertices[4];
+  RGBAColour  colours[4];
+};
+typedef std::vector<PRCtessquad> PRCtessquadList;
+/*
+struct PRCtesstriangle // textured triangle
+{
+  PRCtesstriangle() : 
+  style(m1) {}
+  PRCVector3d vertices[3];
+// PRCVector3d normals[3];
+// RGBAColour  colors[3];
+  PRCVector2d texcoords[3];
+  uint32_t style;
+};
+typedef std::vector<PRCtesstriangle> PRCtesstriangleList;
+*/
+struct PRCtessline // polyline
+{
+  std::vector<PRCVector3d> point;
+  PRCRgbColor color;
+};
+typedef std::list<PRCtessline> PRCtesslineList;
+typedef std::map<double, PRCtesslineList> PRCtesslineMap;
+
+struct PRCface
+{
+  PRCface() : transform(NULL), face(NULL) {}
+  uint32_t style;
+  bool transparent;
+  PRCGeneralTransformation3d*  transform;
+  PRCFace* face;
+};
+typedef std::vector <PRCface>  PRCfaceList;
+
+struct PRCcompface
+{
+  PRCcompface() : face(NULL) {}
+  uint32_t style;
+  bool transparent;
+  PRCCompressedFace* face;
+};
+typedef std::vector <PRCcompface>  PRCcompfaceList;
+
+struct PRCwire
+{
+  PRCwire() : style(m1), transform(NULL), curve(NULL) {}
+  uint32_t style;
+  PRCGeneralTransformation3d*  transform;
+  PRCCurve* curve;
+};
+typedef std::vector <PRCwire>  PRCwireList;
+
+typedef std::map <uint32_t,std::vector<PRCVector3d> >  PRCpointsetMap;
+
+class PRCoptions
+{
+public:
+  double compression;
+  double granularity;
+
+  bool closed;   // render the surface as one-sided; may yield faster rendering
+  bool tess;     // use tessellated mesh to store straight patches
+  bool do_break; //
+  bool no_break; // do not render transparent patches as one-faced nodes
+
+  PRCoptions(double compression=0.0, double granularity=0.0, bool closed=false,
+             bool tess=false, bool do_break=true, bool no_break=false)
+    : compression(compression), granularity(granularity), closed(closed),
+      tess(tess), do_break(do_break), no_break(no_break) {}
+};
+
+class PRCgroup
+{
+ public:
+  PRCgroup() : 
+    product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {}
+  PRCgroup(const std::string& name) : 
+    product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {}
+  PRCProductOccurrence *product_occurrence, *parent_product_occurrence;
+  PRCPartDefinition *part_definition, *parent_part_definition;
+  PRCfaceList       faces;
+  PRCcompfaceList   compfaces;
+  PRCtessrectangleList  rectangles;
+// PRCtesstriangleList   triangles;
+  PRCtessquadList       quads;
+  PRCtesslineMap        lines;
+  PRCwireList           wires;
+  PRCpointsetMap        points;
+  std::vector<PRCPointSet*>      pointsets;
+  std::vector<PRCPolyBrepModel*> polymodels;
+  std::vector<PRCPolyWire*>      polywires;
+  PRCGeneralTransformation3d*  transform;
+  std::string name;
+  PRCoptions options;
+};
+
+void makeFileUUID(PRCUniqueId&);
+void makeAppUUID(PRCUniqueId&);
+
+class PRCUncompressedFile
+{
+  public:
+    PRCUncompressedFile() : file_size(0), data(NULL) {}
+    PRCUncompressedFile(uint32_t fs, uint8_t* d) : file_size(fs), data(d) {}
+    ~PRCUncompressedFile() { if(data != NULL) delete[] data; }
+    uint32_t file_size;
+    uint8_t* data;
+
+    void write(std::ostream&) const;
+
+    uint32_t getSize() const;
+};
+typedef std::deque <PRCUncompressedFile*>  PRCUncompressedFileList;
+
+class PRCStartHeader
+{
+  public:
+    uint32_t minimal_version_for_read; // PRCVersion
+    uint32_t authoring_version; // PRCVersion
+    PRCUniqueId file_structure_uuid;
+    PRCUniqueId application_uuid; // should be 0
+
+    PRCStartHeader() :
+      minimal_version_for_read(PRCVersion), authoring_version(PRCVersion) {}
+    void serializeStartHeader(std::ostream&) const;
+
+    uint32_t getStartHeaderSize() const;
+};
+
+class PRCFileStructure : public PRCStartHeader
+{
+  public:
+    uint32_t number_of_referenced_file_structures;
+    double tessellation_chord_height_ratio;
+    double tessellation_angle_degree;
+    std::string default_font_family_name;
+    std::vector<PRCRgbColor> colors;
+    std::vector<PRCPicture> pictures;
+    PRCUncompressedFileList uncompressed_files;
+    PRCTextureDefinitionList texture_definitions;
+    PRCMaterialList materials;
+    PRCStyleList styles;
+    PRCCoordinateSystemList reference_coordinate_systems;
+    std::vector<PRCFontKeysSameFont> font_keys_of_font;
+    PRCPartDefinitionList part_definitions;
+    PRCProductOccurrenceList product_occurrences;
+//  PRCMarkupList markups;
+//  PRCAnnotationItemList annotation_entities;
+    double unit;
+    PRCTopoContextList contexts;
+    PRCTessList tessellations;
+
+    uint32_t sizes[6];
+    uint8_t* globals_data;
+    PRCbitStream globals_out; // order matters: PRCbitStream must be initialized last
+    uint8_t* tree_data;
+    PRCbitStream tree_out;
+    uint8_t* tessellations_data;
+    PRCbitStream tessellations_out;
+    uint8_t* geometry_data;
+    PRCbitStream geometry_out;
+    uint8_t* extraGeometry_data;
+    PRCbitStream extraGeometry_out;
+
+    ~PRCFileStructure () {
+      for(PRCUncompressedFileList::iterator  it=uncompressed_files.begin();  it!=uncompressed_files.end();  ++it) delete *it;
+      for(PRCTextureDefinitionList::iterator it=texture_definitions.begin(); it!=texture_definitions.end(); ++it) delete *it;
+      for(PRCMaterialList::iterator          it=materials.begin();           it!=materials.end();           ++it) delete *it;
+      for(PRCStyleList::iterator             it=styles.begin();              it!=styles.end();              ++it) delete *it;
+      for(PRCTopoContextList::iterator       it=contexts.begin();            it!=contexts.end();            ++it) delete *it;
+      for(PRCTessList::iterator              it=tessellations.begin();       it!=tessellations.end();       ++it) delete *it;
+      for(PRCPartDefinitionList::iterator    it=part_definitions.begin();    it!=part_definitions.end();    ++it) delete *it;
+      for(PRCProductOccurrenceList::iterator it=product_occurrences.begin(); it!=product_occurrences.end(); ++it) delete *it;
+      for(PRCCoordinateSystemList::iterator  it=reference_coordinate_systems.begin(); it!=reference_coordinate_systems.end(); it++)
+        delete *it;
+
+      free(globals_data);
+      free(tree_data);
+      free(tessellations_data);
+      free(geometry_data);
+      free(extraGeometry_data);
+    }
+
+    PRCFileStructure() :
+      number_of_referenced_file_structures(0),
+      tessellation_chord_height_ratio(2000.0),tessellation_angle_degree(40.0),
+      default_font_family_name(""),
+      unit(1),
+      globals_data(NULL),globals_out(globals_data,0),
+      tree_data(NULL),tree_out(tree_data,0),
+      tessellations_data(NULL),tessellations_out(tessellations_data,0),
+      geometry_data(NULL),geometry_out(geometry_data,0),
+      extraGeometry_data(NULL),extraGeometry_out(extraGeometry_data,0) {}
+    void write(std::ostream&);
+    void prepare();
+    uint32_t getSize();
+    void serializeFileStructureGlobals(PRCbitStream&);
+    void serializeFileStructureTree(PRCbitStream&);
+    void serializeFileStructureTessellation(PRCbitStream&);
+    void serializeFileStructureGeometry(PRCbitStream&);
+    void serializeFileStructureExtraGeometry(PRCbitStream&);
+    uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t* picture, uint32_t width=0, uint32_t height=0, std::string name="");
+    uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition);
+    uint32_t addRgbColor(const PRCRgbColor& color);
+    uint32_t addRgbColorUnique(const PRCRgbColor& color);
+    uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric);
+    uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication);
+    uint32_t addStyle(PRCStyle*& pStyle);
+    uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition);
+    uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence);
+    uint32_t addTopoContext(PRCTopoContext*& pTopoContext);
+    uint32_t getTopoContext(PRCTopoContext*& pTopoContext);
+    uint32_t add3DTess(PRC3DTess*& p3DTess);
+    uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess);
+/*
+    uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess);
+    uint32_t addMarkup(PRCMarkup*& pMarkup);
+    uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem);
+ */
+    uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem);
+    uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem);
+};
+
+class PRCFileStructureInformation
+{
+  public:
+    PRCUniqueId UUID;
+    uint32_t reserved; // 0
+    uint32_t number_of_offsets;
+    uint32_t* offsets;
+
+    void write(std::ostream&);
+
+    uint32_t getSize();
+};
+
+class PRCHeader : public PRCStartHeader
+{
+  public :
+    uint32_t number_of_file_structures;
+    PRCFileStructureInformation* fileStructureInformation;
+    uint32_t model_file_offset;
+    uint32_t file_size; // not documented
+    PRCUncompressedFileList uncompressed_files;
+
+    void write(std::ostream&);
+    uint32_t getSize();
+};
+
+typedef std::map <PRCGeneralTransformation3d,uint32_t> PRCtransformMap;
+
+class oPRCFile
+{
+  public:
+    oPRCFile(std::ostream& os, double u=1, uint32_t n=1) :
+      number_of_file_structures(n),
+      fileStructures(new PRCFileStructure*[n]),
+      unit(u),
+      modelFile_data(NULL),modelFile_out(modelFile_data,0),
+      fout(NULL),output(os)
+      {
+        for(uint32_t i = 0; i < number_of_file_structures; ++i)
+        {
+          fileStructures[i] = new PRCFileStructure();
+          fileStructures[i]->minimal_version_for_read = PRCVersion;
+          fileStructures[i]->authoring_version = PRCVersion;
+          makeFileUUID(fileStructures[i]->file_structure_uuid);
+          makeAppUUID(fileStructures[i]->application_uuid);
+          fileStructures[i]->unit = u;
+        }
+
+        groups.push(PRCgroup());
+        PRCgroup &group = groups.top();
+        group.name="root";
+        group.transform = NULL;
+        group.product_occurrence = new PRCProductOccurrence(group.name);
+        group.parent_product_occurrence = NULL;
+        group.part_definition = new PRCPartDefinition;
+        group.parent_part_definition = NULL;
+      }
+
+    oPRCFile(const std::string& name, double u=1, uint32_t n=1) :
+      number_of_file_structures(n),
+      fileStructures(new PRCFileStructure*[n]),
+      unit(u),
+      modelFile_data(NULL),modelFile_out(modelFile_data,0),
+      fout(new std::ofstream(name.c_str(),
+                             std::ios::out|std::ios::binary|std::ios::trunc)),
+      output(*fout)
+      {
+        for(uint32_t i = 0; i < number_of_file_structures; ++i)
+        {
+          fileStructures[i] = new PRCFileStructure();
+          fileStructures[i]->minimal_version_for_read = PRCVersion;
+          fileStructures[i]->authoring_version = PRCVersion;
+          makeFileUUID(fileStructures[i]->file_structure_uuid);
+          makeAppUUID(fileStructures[i]->application_uuid);
+          fileStructures[i]->unit = u;
+        }
+
+        groups.push(PRCgroup());
+        PRCgroup &group = groups.top();
+        group.name="root";
+        group.transform = NULL;
+        group.product_occurrence = new PRCProductOccurrence(group.name);
+        group.parent_product_occurrence = NULL;
+        group.part_definition = new PRCPartDefinition;
+        group.parent_part_definition = NULL;
+     }
+
+    ~oPRCFile()
+    {
+      for(uint32_t i = 0; i < number_of_file_structures; ++i)
+        delete fileStructures[i];
+      delete[] fileStructures;
+      if(fout != NULL)
+        delete fout;
+      free(modelFile_data);
+      for(PRCpictureMap::iterator it=pictureMap.begin(); it!=pictureMap.end(); ++it) delete it->first.data;
+    }
+
+    void begingroup(const char* name, PRCoptions* options=NULL,
+                    const double* t=NULL);
+    void endgroup();
+
+    std::string lastgroupname;
+    std::vector<std::string> lastgroupnames;
+    std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence);
+    
+    bool finish();
+    uint32_t getSize();
+
+    const uint32_t number_of_file_structures;
+    PRCFileStructure** fileStructures;
+    PRCHeader header;
+    PRCUnit unit;
+    uint8_t* modelFile_data;
+    PRCbitStream modelFile_out; // order matters: PRCbitStream must be initialized last
+    PRCcolorMap colorMap;
+    PRCcolourMap colourMap;
+    PRCcolourwidthMap colourwidthMap;
+    PRCmaterialgenericMap materialgenericMap;
+    PRCtexturedefinitionMap texturedefinitionMap;
+    PRCtextureapplicationMap textureapplicationMap;
+    PRCstyleMap styleMap;
+    PRCpictureMap pictureMap;
+    PRCgroup rootGroup;
+    PRCtransformMap transformMap;
+    std::stack<PRCgroup> groups;
+    PRCgroup& findGroup();
+    void doGroup(PRCgroup& group);
+    uint32_t addColor(const PRCRgbColor& color);
+    uint32_t addColour(const RGBAColour& colour);
+    uint32_t addColourWidth(const RGBAColour& colour, double width);
+    uint32_t addLineMaterial(const RGBAColour& c, double width)
+               { return addColourWidth(c,width); }
+    uint32_t addMaterial(const PRCmaterial& material);
+    uint32_t addTransform(PRCGeneralTransformation3d*& transform);
+    uint32_t addTransform(const double* t);
+    uint32_t addTransform(const double origin[3], const double x_axis[3], const double y_axis[3], double scale);
+    void addPoint(const double P[3], const RGBAColour& c, double w=1.0);
+    void addPoints(uint32_t n, const double P[][3], const RGBAColour& c, double w=1.0);
+    void addLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+                      const RGBAColour& c, double w,
+                      bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+    uint32_t createLines(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[],
+                      bool segment_color, uint32_t nC, const RGBAColour C[], uint32_t nCI, const uint32_t CI[]);
+    void addTriangles(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[]);
+    uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], uint32_t style_index,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nS, const uint32_t S[], const uint32_t SI[]);
+    uint32_t createTriangleMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][3], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][3],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][3],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][3],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[])
+            {
+               const uint32_t style = addMaterial(m);
+               if(M!=NULL && nM>0)
+               {
+                 uint32_t* const styles = new uint32_t[nM];
+                 for(uint32_t i=0; i<nM; i++)
+                   styles[i]=addMaterial(M[i]);
+                 const uint32_t meshid =  createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI);
+                 delete[] styles;
+                 return meshid;
+               }
+               else
+                 return createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL);
+            }
+    void addQuads(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[]);
+    uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], uint32_t style_index,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nS, const uint32_t S[],    const uint32_t SI[]);
+    uint32_t createQuadMesh(uint32_t nP, const double P[][3], uint32_t nI, const uint32_t PI[][4], const PRCmaterial& m,
+                      uint32_t nN, const double N[][3],   const uint32_t NI[][4],
+                      uint32_t nT, const double T[][2],   const uint32_t TI[][4],
+                      uint32_t nC, const RGBAColour C[],  const uint32_t CI[][4],
+                      uint32_t nM, const PRCmaterial M[], const uint32_t MI[])
+            {
+               const uint32_t style = addMaterial(m);
+               if(M!=NULL && nM>0)
+               {
+                 uint32_t* const styles = new uint32_t[nM];
+                 for(uint32_t i=0; i<nM; i++)
+                   styles[i]=addMaterial(M[i]);
+                 const uint32_t meshid =  createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, nM, styles, MI);
+                 delete[] styles;
+                 return meshid;
+               }
+               else
+                 return createQuadMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL);
+            }
+#define PRCTRANSFORM const double origin[3]=NULL, const double x_axis[3]=NULL, const double y_axis[3]=NULL, double scale=1, const double* t=NULL
+#define PRCCARTRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale
+#define PRCGENTRANSFORM const double* t=NULL
+#define PRCNOMATERIALINDEX m1
+    void useMesh(uint32_t tess_index, uint32_t style_index,            PRCGENTRANSFORM);
+    void useMesh(uint32_t tess_index, const PRCmaterial& m,            PRCGENTRANSFORM)
+           { useMesh(tess_index,addMaterial(m),t); }
+    void useMesh(uint32_t tess_index, uint32_t style_index,            PRCCARTRANSFORM);
+    void useMesh(uint32_t tess_index, const PRCmaterial& m,            PRCCARTRANSFORM)
+           { useMesh(tess_index,addMaterial(m),origin, x_axis, y_axis, scale); }
+
+    void useLines(uint32_t tess_index, uint32_t style_index,           PRCGENTRANSFORM);
+    void useLines(uint32_t tess_index, const RGBAColour& c,  double w, PRCGENTRANSFORM)
+           { useLines(tess_index, addLineMaterial(c,w), t); }
+    void useLines(uint32_t tess_index, uint32_t style_index,           PRCCARTRANSFORM);
+    void useLines(uint32_t tess_index, const RGBAColour& c,  double w, PRCCARTRANSFORM)
+           { useLines(tess_index,addLineMaterial(c,w),origin, x_axis, y_axis, scale); }
+
+//  void addTriangle(const double P[][3], const double T[][2], uint32_t style_index);
+  
+    void addLine(uint32_t n, const double P[][3], const RGBAColour& c, double w=1.0);
+    void addBezierCurve(uint32_t n, const double cP[][3], const RGBAColour& c);
+    void addCurve(uint32_t d, uint32_t n, const double cP[][3], const double* k, const RGBAColour& c, const double w[]);
+    void addQuad(const double P[][3], const RGBAColour C[]);
+
+    void addRectangle(const double P[][3], const PRCmaterial& m);
+    void addPatch(const double cP[][3], const PRCmaterial& m);
+    void addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
+     const double cP[][3], const double* kU, const double* kV, const PRCmaterial& m,
+     const double w[]);
+    void addTube(uint32_t n, const double cP[][3], const double oP[][3], bool straight, const PRCmaterial& m, PRCTRANSFORM);
+    void addHemisphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addSphere(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addDisk(double radius, const PRCmaterial& m, PRCTRANSFORM);
+    void addCylinder(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+    void addCone(double radius, double height, const PRCmaterial& m, PRCTRANSFORM);
+    void addTorus(double major_radius, double minor_radius, double angle1, double angle2, const PRCmaterial& m, PRCTRANSFORM);
+#undef PRCTRANSFORM
+#undef PRCCARTRANSFORM
+#undef PRCGENTRANSFORM
+
+
+    uint32_t addPicture(EPRCPictureDataFormat format, uint32_t size, const uint8_t* picture, uint32_t width=0, uint32_t height=0,
+      std::string name="", uint32_t fileStructure=0)
+      { return fileStructures[fileStructure]->addPicture(format, size, picture, width, height, name); }
+    uint32_t addPicture(const PRCpicture& pic,
+      std::string name="", uint32_t fileStructure=0)
+      { return fileStructures[fileStructure]->addPicture(pic.format, pic.size, pic.data, pic.width, pic.height, name); }
+    uint32_t addTextureDefinition(PRCTextureDefinition*& pTextureDefinition, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addTextureDefinition(pTextureDefinition);
+      }
+    uint32_t addTextureApplication(PRCTextureApplication*& pTextureApplication, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addTextureApplication(pTextureApplication);
+      }
+    uint32_t addRgbColor(const PRCRgbColor& color,
+       uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addRgbColor(color);
+      }
+    uint32_t addRgbColorUnique(const PRCRgbColor& color,
+       uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addRgbColorUnique(color);
+      }
+    uint32_t addMaterialGeneric(PRCMaterialGeneric*& pMaterialGeneric,
+       uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addMaterialGeneric(pMaterialGeneric);
+      }
+    uint32_t addStyle(PRCStyle*& pStyle, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addStyle(pStyle);
+      }
+    uint32_t addPartDefinition(PRCPartDefinition*& pPartDefinition, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addPartDefinition(pPartDefinition);
+      }
+    uint32_t addProductOccurrence(PRCProductOccurrence*& pProductOccurrence, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addProductOccurrence(pProductOccurrence);
+      }
+    uint32_t addTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addTopoContext(pTopoContext);
+      }
+    uint32_t getTopoContext(PRCTopoContext*& pTopoContext, uint32_t fileStructure=0)
+    {
+      return fileStructures[fileStructure]->getTopoContext(pTopoContext);
+    }
+    uint32_t add3DTess(PRC3DTess*& p3DTess, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->add3DTess(p3DTess);
+      }
+    uint32_t add3DWireTess(PRC3DWireTess*& p3DWireTess, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->add3DWireTess(p3DWireTess);
+      }
+/*
+    uint32_t addMarkupTess(PRCMarkupTess*& pMarkupTess, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addMarkupTess(pMarkupTess);
+      }
+    uint32_t addMarkup(PRCMarkup*& pMarkup, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addMarkup(pMarkup);
+      }
+    uint32_t addAnnotationItem(PRCAnnotationItem*& pAnnotationItem, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addAnnotationItem(pAnnotationItem);
+      }
+ */
+    uint32_t addCoordinateSystem(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addCoordinateSystem(pCoordinateSystem);
+      }
+    uint32_t addCoordinateSystemUnique(PRCCoordinateSystem*& pCoordinateSystem, uint32_t fileStructure=0)
+      {
+        return fileStructures[fileStructure]->addCoordinateSystemUnique(pCoordinateSystem);
+      }
+  private:
+    void serializeModelFileData(PRCbitStream&);
+    std::ofstream* fout;
+    std::ostream& output;
+};
+
+#endif // __O_PRC_FILE_H
diff --git a/src/prc/writePRC.cc b/src/prc/writePRC.cc
new file mode 100644 (file)
index 0000000..8265d0b
--- /dev/null
@@ -0,0 +1,2083 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*   with enhancements contributed by Michail Vidiassov.
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include "writePRC.h"
+#include <climits>
+#include <cassert>
+
+// debug print includes
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+
+#if !defined(__GNUC__) || defined(__clang__)
+#include <vector>
+#endif
+
+using namespace std;
+
+#ifndef __GNUC_PREREQ
+#define __GNUC_PREREQ(maj, min) (0)
+#endif
+
+// Count leading zeros.
+uint32_t CLZ(uint32_t a) 
+{
+#if __GNUC_PREREQ(3,4)
+  return __builtin_clz(a);
+#else
+// find the log base 2 of a 32-bit integer
+  static const int MultiplyDeBruijnBitPosition[32] = {
+    0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
+    8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
+  };
+
+  a |= a >> 1; // first round down to one less than a power of 2 
+  a |= a >> 2;
+  a |= a >> 4;
+  a |= a >> 8;
+  a |= a >> 16;
+
+  return 31-MultiplyDeBruijnBitPosition[(uint32_t)(a * 0x07C4ACDDU) >> 27];
+#endif
+}
+
+// Portable integer implementation of ceil(log2(x)).
+uint32_t Log2(uint32_t x) 
+{
+  assert(x != 0);
+  uint32_t L=31-CLZ(x);
+  return ((uint32_t) 1 << L == x) ? L : L+1;
+}
+
+#define WriteUnsignedInteger( value ) pbs << (uint32_t)(value);
+#define WriteInteger( value ) pbs << (int32_t)(value);
+#define WriteCharacter( value ) pbs << (uint8_t)(value);
+#define WriteDouble( value ) pbs << (double)(value);
+#define WriteBit( value ) pbs << (bool)(value);
+#define WriteBoolean( value ) pbs << (bool)(value);
+#define WriteString( value ) pbs << (value);
+#define SerializeContentPRCBase serializeContentPRCBase(pbs);
+#define SerializeGraphics serializeGraphics(pbs);
+#define SerializePRCBaseWithGraphics { serializeContentPRCBase(pbs); serializeGraphics(pbs); }
+#define SerializeRepresentationItemContent serializeRepresentationItemContent(pbs);
+#define SerializeRepresentationItem( value ) (value)->serializeRepresentationItem(pbs);
+#define SerializeMarkup( value ) (value).serializeMarkup(pbs);
+#define SerializeReferenceUniqueIdentifier( value ) (value).serializeReferenceUniqueIdentifier(pbs);
+#define SerializeContentBaseTessData serializeContentBaseTessData(pbs);
+#define SerializeTessFace( value ) (value)->serializeTessFace(pbs);
+#define SerializeUserData UserData(0,0).write(pbs);
+#define SerializeLineAttr( value ) pbs << (uint32_t)((value)+1);
+#define SerializeVector3d( value ) (value).serializeVector3d(pbs);
+#define SerializeVector2d( value ) (value).serializeVector2d(pbs);
+#define SerializeName( value ) writeName(pbs, (value));
+#define SerializeInterval( value )  (value).serializeInterval(pbs);
+// #define SerializeBoundingBox( value )  (value).serializeBoundingBox(pbs);
+#define SerializeDomain( value )  (value).serializeDomain(pbs);
+#define SerializeParameterization  serializeParameterization(pbs);
+#define SerializeUVParameterization  serializeUVParameterization(pbs);
+#define SerializeTransformation  serializeTransformation(pbs);
+#define SerializeBaseTopology  serializeBaseTopology(pbs);
+#define SerializeBaseGeometry  serializeBaseGeometry(pbs);
+#define SerializePtrCurve( value )    {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeCurve(pbs);}
+#define SerializePtrSurface( value )  {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeSurface(pbs);}
+#define SerializePtrTopology( value ) {WriteBoolean( false ); if((value)==NULL) pbs << (uint32_t)PRC_TYPE_ROOT; else (value)->serializeTopoItem(pbs);}
+#define SerializeContentCurve  serializeContentCurve(pbs);
+#define SerializeContentWireEdge  serializeContentWireEdge(pbs);
+#define SerializeContentBody  serializeContentBody(pbs);
+#define SerializeTopoContext  serializeTopoContext(pbs);
+#define SerializeContextAndBodies( value )  (value).serializeContextAndBodies(pbs);
+#define SerializeBody( value )  (value)->serializeBody(pbs);
+#define ResetCurrentGraphics resetGraphics();
+#define SerializeContentSurface  serializeContentSurface(pbs);
+#define SerializeCompressedUniqueId( value ) (value).serializeCompressedUniqueId(pbs);
+#define SerializeUnit( value ) (value).serializeUnit(pbs);
+#define SerializeBoundingBox serializeBoundingBox(pbs);
+#define SerializeAttributeEntry serializeAttributeEntry(pbs);
+#define SerializeContentSingleAttribute( value ) (value).serializeSingleAttribute(pbs);
+#define SerializeAttribute( value ) (value).serializeAttribute(pbs);
+#define SerializeAttributeData serializeAttributes(pbs);
+#define WriteUncompressedUnsignedInteger( value ) writeUncompressedUnsignedInteger(out, (uint32_t)(value));
+#define SerializeFileStructureUncompressedUniqueId( value ) (value).serializeFileStructureUncompressedUniqueId(out);
+
+void writeUncompressedUnsignedInteger(ostream &out, uint32_t data)
+{
+#ifdef WORDS_BIGENDIAN
+  out.write(((char*)&data)+3,1);
+  out.write(((char*)&data)+2,1);
+  out.write(((char*)&data)+1,1);
+  out.write(((char*)&data)+0,1);
+#else
+  out.write(((char*)&data)+0,1);
+  out.write(((char*)&data)+1,1);
+  out.write(((char*)&data)+2,1);
+  out.write(((char*)&data)+3,1);
+#endif
+}
+
+double PRCVector3d::Length()
+{
+  return sqrt(x*x+y*y+z*z);
+}
+
+bool PRCVector3d::Normalize()
+{
+ double fLength=Length();
+ if(fLength < FLT_EPSILON) return false;
+ double factor=1.0/fLength;
+ x *= factor;
+ y *= factor;
+ z *= factor;
+ return true;
+}
+
+double PRCVector2d::Length()
+{
+  return sqrt(x*x+y*y);
+}
+
+bool PRCVector2d::Normalize()
+{
+  double fLength=Length();
+  if(fLength < FLT_EPSILON) return false;
+  double factor=1.0/fLength;
+  x *= factor;
+  y *= factor;
+
+  return true;
+}
+
+void UserData::write(PRCbitStream &pbs)
+{
+  pbs << size;
+  if(size > 0) {
+    uint32_t quot=size/8;
+    uint32_t rem=size-8*quot;
+    for(uint32_t i = 0; i < quot; ++i)
+      pbs << data[i];
+    for(uint32_t j = 0; j < rem; ++j) // 0-based, big endian bit counting
+      pbs << (bool)((data[quot] & (0x80 >> j))!=0);
+  }
+}
+
+void PRCAttributeEntry::serializeAttributeEntry(PRCbitStream &pbs) const
+{
+  WriteBoolean (title_is_integer) 
+  if (title_is_integer)
+    WriteUnsignedInteger (title_integer)
+  else 
+    WriteString (title_text)
+}
+
+void PRCSingleAttribute::serializeSingleAttribute(PRCbitStream &pbs) const
+{
+  SerializeAttributeEntry
+  WriteUnsignedInteger (type)
+  switch (type)
+  {
+    case KEPRCModellerAttributeTypeInt:
+      WriteInteger (value.integer)
+      break;
+    case KEPRCModellerAttributeTypeReal:
+      WriteDouble (value.real)
+      break;
+    case KEPRCModellerAttributeTypeTime:
+      WriteUnsignedInteger (value.time)
+      break;
+    case KEPRCModellerAttributeTypeString:
+      WriteString (value_text)
+      break; 
+    default:
+      break;
+  }
+}
+
+void PRCAttribute::serializeAttribute(PRCbitStream &pbs) const
+{
+  WriteUnsignedInteger (PRC_TYPE_MISC_Attribute) 
+  
+  SerializeAttributeEntry
+  const uint32_t size_of_attribute_keys = attribute_keys.size();
+  WriteUnsignedInteger (size_of_attribute_keys) 
+  for(uint32_t i=0;i<size_of_attribute_keys;i++) 
+    SerializeContentSingleAttribute (attribute_keys[i]) 
+}
+
+void PRCAttributes::serializeAttributes(PRCbitStream &pbs) const
+{
+  if (attributes.empty()) { // shortcut for most typical case
+    const uint32_t number_of_attributes = 0;
+    WriteUnsignedInteger (number_of_attributes) 
+    return;
+  }
+  const uint32_t number_of_attributes = attributes.size();
+  WriteUnsignedInteger (number_of_attributes) 
+  for(PRCAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it)
+  {
+    SerializeAttribute(*it)
+  }
+}
+
+void ContentPRCBase::serializeContentPRCBase(PRCbitStream &pbs) const
+{
+  SerializeAttributeData
+
+  SerializeName (name)
+  if (type_eligible_for_reference(type))
+  {
+    WriteUnsignedInteger (CAD_identifier)
+    WriteUnsignedInteger (CAD_persistent_identifier)
+    WriteUnsignedInteger (PRC_unique_identifier)
+  }
+}
+
+
+bool IsCompressedType(uint32_t type)
+{
+  return (type == PRC_TYPE_TOPO_BrepDataCompress || type == PRC_TYPE_TOPO_SingleWireBodyCompress || type == PRC_TYPE_TESS_3D_Compressed);
+}
+
+void PRCReferenceUniqueIdentifier::serializeReferenceUniqueIdentifier(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_MISC_ReferenceOnPRCBase)
+  WriteUnsignedInteger (type)
+  const bool reference_in_same_file_structure = true;
+  WriteBoolean (reference_in_same_file_structure)
+// if (!reference_in_same_file_structure)
+//    SerializeCompressedUniqueId (target_file_structure)
+  WriteUnsignedInteger (unique_identifier)
+}
+
+void PRCRgbColor::serializeRgbColor(PRCbitStream &pbs)
+{
+  WriteDouble (red)
+  WriteDouble (green)
+  WriteDouble (blue)
+}
+
+void PRCPicture::serializePicture(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_Picture)
+  SerializeContentPRCBase
+  WriteInteger (format) //see Types for picture files
+  WriteUnsignedInteger (uncompressed_file_index+1)
+  WriteUnsignedInteger (pixel_width)
+  WriteUnsignedInteger (pixel_height)
+}
+
+void PRCTextureDefinition::serializeTextureDefinition(PRCbitStream &pbs)
+{
+  uint32_t i=0; // universal index for PRC standart compatibility
+  const uint8_t texture_dimension = 2;
+  const uint32_t texture_mapping_attributes = texture_mapping_attribute;
+  const uint32_t size_texture_mapping_attributes_intensities = 1;
+  const double *texture_mapping_attributes_intensities = &texture_mapping_attribute_intensity;
+  const uint32_t size_texture_mapping_attributes_components = 1;
+  const uint8_t *texture_mapping_attributes_components = &texture_mapping_attribute_components;
+  const EPRCTextureMappingType eMappingType = KEPRCTextureMappingType_Stored;
+  
+  const double red = 1.0;
+  const double green = 1.0;
+  const double blue = 1.0;
+  const double alpha = 1.0;
+  const EPRCTextureBlendParameter blend_src_rgb = KEPRCTextureBlendParameter_Unknown;
+  const EPRCTextureBlendParameter blend_dst_rgb = KEPRCTextureBlendParameter_Unknown;
+  const EPRCTextureBlendParameter blend_src_alpha = KEPRCTextureBlendParameter_Unknown;
+  const EPRCTextureBlendParameter blend_dst_alpha = KEPRCTextureBlendParameter_Unknown;
+  const EPRCTextureAlphaTest alpha_test = KEPRCTextureAlphaTest_Unknown;
+  const double alpha_test_reference = 1.0;
+  const EPRCTextureWrappingMode texture_wrapping_mode_R = KEPRCTextureWrappingMode_ClampToBorder;
+  const bool texture_transformation = false;
+
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureDefinition)
+
+  SerializeContentPRCBase
+
+  WriteUnsignedInteger (picture_index+1) 
+  WriteCharacter (texture_dimension) 
+
+  //   SerializeTextureMappingType
+  WriteInteger (eMappingType) // Texture mapping type
+  //  if (eMappingType == TEXTURE_MAPPING_OPERATOR)
+  //  {
+  //     WriteInteger (eMappingOperator) // Texture mapping operator
+  //     WriteInteger (transformation)
+  //     if (transformation)
+  //        SerializeCartesianTransformation3d (transformation) 
+  //  }
+
+  WriteUnsignedInteger (texture_mapping_attributes) // Texture mapping attributes 
+  WriteUnsignedInteger (size_texture_mapping_attributes_intensities)
+  for (i=0;i<size_texture_mapping_attributes_intensities;i++)
+     WriteDouble (texture_mapping_attributes_intensities[i])
+  WriteUnsignedInteger (size_texture_mapping_attributes_components)
+  for (i=0;i<size_texture_mapping_attributes_components;i++)
+     WriteCharacter (texture_mapping_attributes_components[i]) 
+
+  WriteInteger (texture_function)
+  // reserved for future use; see Texture function 
+  if (texture_function == KEPRCTextureFunction_Blend)
+  {
+     WriteDouble (red) // blend color component in the range [0.0,1.0]
+     WriteDouble (green) // blend color component in the range [0.0,1.0]
+     WriteDouble (blue) // blend color component in the range [0.0,1.0]
+     WriteDouble (alpha) // blend color component in the range [0.0,1.0]
+  }
+
+  WriteInteger (blend_src_rgb) // Texture blend parameter 
+  // reserved for future use; see Texture blend parameter 
+  if (blend_src_rgb != KEPRCTextureBlendParameter_Unknown)
+     WriteInteger (blend_dst_rgb) // Texture blend parameter 
+
+  WriteInteger (blend_src_alpha) // Texture blend parameter 
+  // reserved for future use; see Texture blend parameter 
+  if (blend_src_alpha != KEPRCTextureBlendParameter_Unknown)
+     WriteInteger (blend_dst_alpha) // Texture blend parameter 
+
+  WriteCharacter (texture_applying_mode) // Texture applying mode 
+  if (texture_applying_mode & PRC_TEXTURE_APPLYING_MODE_ALPHATEST)
+  {
+     WriteInteger (alpha_test) // Texture alpha test 
+     WriteDouble (alpha_test_reference)
+  }
+
+  WriteInteger (texture_wrapping_mode_S) // Texture wrapping mode
+  if (texture_dimension > 1)
+     WriteInteger (texture_wrapping_mode_T) // Texture wrapping mode
+  if (texture_dimension > 2 )
+     WriteInteger (texture_wrapping_mode_R) // Texture wrapping mode
+
+  WriteBit (texture_transformation)
+//  if (texture_transformation)
+//     SerializeTextureTransformation (texture_transformation)
+}
+
+void PRCMaterialGeneric::serializeMaterialGeneric(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_Material)
+  SerializeContentPRCBase
+  WriteUnsignedInteger (ambient + 1)
+  WriteUnsignedInteger (diffuse + 1)
+  WriteUnsignedInteger (emissive + 1)
+  WriteUnsignedInteger (specular + 1)
+  WriteDouble (shininess)
+  WriteDouble (ambient_alpha)
+  WriteDouble (diffuse_alpha)
+  WriteDouble (emissive_alpha)
+  WriteDouble (specular_alpha)
+}
+
+void PRCTextureApplication::serializeTextureApplication(PRCbitStream &pbs) 
+{
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_TextureApplication)
+  SerializeContentPRCBase
+
+  WriteUnsignedInteger (material_generic_index+1) 
+  WriteUnsignedInteger (texture_definition_index+1) 
+  WriteUnsignedInteger (next_texture_index+1) 
+  WriteUnsignedInteger (UV_coordinates_index+1)
+}
+
+void PRCLinePattern::serializeLinePattern(PRCbitStream &pbs)
+{
+  uint32_t i = 0;
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_LinePattern)
+  SerializeContentPRCBase
+  
+  const uint32_t size_lengths = lengths.size();
+  WriteUnsignedInteger (size_lengths)
+  for (i=0;i<size_lengths;i++)
+    WriteDouble (lengths[i])
+  WriteDouble (phase)
+  WriteBoolean (is_real_length)
+}
+
+
+void PRCStyle::serializeCategory1LineStyle(PRCbitStream &pbs)
+{
+  const bool is_additional_1_defined = (additional!=0);
+  const uint8_t additional_1 = additional;
+  const bool is_additional_2_defined = false;
+  const uint8_t additional_2 = 0;
+  const bool is_additional_3_defined = false;
+  const uint8_t additional_3 = 0;
+  WriteUnsignedInteger (PRC_TYPE_GRAPH_Style)
+  SerializeContentPRCBase
+  WriteDouble (line_width)
+  WriteBoolean (is_vpicture)
+  WriteUnsignedInteger (line_pattern_vpicture_index + 1)
+  WriteBoolean (is_material)
+  WriteUnsignedInteger (color_material_index + 1)
+  WriteBoolean (is_transparency_defined)
+  if (is_transparency_defined)
+     WriteCharacter (transparency)
+  WriteBoolean (is_additional_1_defined)
+  if (is_additional_1_defined)
+     WriteCharacter (additional_1)
+  WriteBoolean (is_additional_2_defined)
+  if (is_additional_2_defined)
+     WriteCharacter (additional_2)
+  WriteBoolean (is_additional_3_defined)
+  if (is_additional_3_defined)
+     WriteCharacter (additional_3)
+}
+
+std::string currentName;
+
+void writeName(PRCbitStream &pbs,const std::string &name)
+{
+  pbs << (name == currentName);
+  if(name != currentName)
+  {
+    pbs << name;
+    currentName = name;
+  }
+}
+
+void resetName()
+{
+  currentName = "";
+}
+
+uint32_t current_layer_index = m1;
+uint32_t current_index_of_line_style = m1;
+uint16_t current_behaviour_bit_field = 1;
+
+void writeGraphics(PRCbitStream &pbs,uint32_t l,uint32_t i,uint16_t b,bool force)
+{
+  if(force || current_layer_index != l || current_index_of_line_style != i || current_behaviour_bit_field != b)
+  {
+    pbs << false << (uint32_t)(l+1) << (uint32_t)(i+1)
+        << (uint8_t)(b&0xFF) << (uint8_t)((b>>8)&0xFF);
+    current_layer_index = l;
+    current_index_of_line_style = i;
+    current_behaviour_bit_field = b;
+  }
+  else
+    pbs << true;
+}
+
+void writeGraphics(PRCbitStream &pbs,const PRCGraphics &graphics,bool force)
+{
+  if(force || current_layer_index != graphics.layer_index || current_index_of_line_style != graphics.index_of_line_style || current_behaviour_bit_field != graphics.behaviour_bit_field)
+  {
+    pbs << false
+        << (uint32_t)(graphics.layer_index+1)
+        << (uint32_t)(graphics.index_of_line_style+1)
+        << (uint8_t)(graphics.behaviour_bit_field&0xFF)
+        << (uint8_t)((graphics.behaviour_bit_field>>8)&0xFF);
+    current_layer_index = graphics.layer_index;
+    current_index_of_line_style = graphics.index_of_line_style;
+    current_behaviour_bit_field = graphics.behaviour_bit_field;
+  }
+  else
+    pbs << true;
+}
+
+void PRCGraphics::serializeGraphics(PRCbitStream &pbs)
+{
+  if(current_layer_index != this->layer_index || current_index_of_line_style != this->index_of_line_style || current_behaviour_bit_field != this->behaviour_bit_field)
+  {
+    pbs << false
+        << (uint32_t)(this->layer_index+1)
+        << (uint32_t)(this->index_of_line_style+1)
+        << (uint8_t)(this->behaviour_bit_field&0xFF)
+        << (uint8_t)((this->behaviour_bit_field>>8)&0xFF);
+    current_layer_index = this->layer_index;
+    current_index_of_line_style = this->index_of_line_style;
+    current_behaviour_bit_field = this->behaviour_bit_field;
+  }
+  else
+    pbs << true;
+}
+
+void PRCGraphics::serializeGraphicsForced(PRCbitStream &pbs)
+{
+  pbs << false
+      << (uint32_t)(this->layer_index+1)
+      << (uint32_t)(this->index_of_line_style+1)
+      << (uint8_t)(this->behaviour_bit_field&0xFF)
+      << (uint8_t)((this->behaviour_bit_field>>8)&0xFF);
+  current_layer_index = this->layer_index;
+  current_index_of_line_style = this->index_of_line_style;
+  current_behaviour_bit_field = this->behaviour_bit_field;
+}
+
+void resetGraphics()
+{
+  current_layer_index = m1;
+  current_index_of_line_style = m1;
+  current_behaviour_bit_field = 1;
+}
+
+void resetGraphicsAndName()
+{
+  resetGraphics(); resetName();
+}
+
+void  PRCMarkup::serializeMarkup(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_MKP_Markup)
+  SerializeContentPRCBase 
+  SerializeGraphics
+  WriteUnsignedInteger (type) 
+  WriteUnsignedInteger (sub_type) 
+  const uint32_t number_of_linked_items = 0;
+  WriteUnsignedInteger (number_of_linked_items) 
+//  for (i=0;i<number_of_linked_items;i++) 
+//     SerializeReferenceUniqueIdentifier (linked_items[i])
+  const uint32_t number_of_leaders = 0;
+  WriteUnsignedInteger (number_of_leaders) 
+//  for (i=0;i<number_of_leaders;i++) 
+//     SerializeReferenceUniqueIdentifier (leaders[i])
+  WriteUnsignedInteger (index_tessellation + 1) 
+  SerializeUserData
+}
+
+void  PRCAnnotationItem::serializeAnnotationItem(PRCbitStream &pbs)
+{
+// group___tf_annotation_item_____serialize2.html
+// group___tf_annotation_item_____serialize_content2.html
+// group___tf_annotation_entity_____serialize_content2.html
+  WriteUnsignedInteger (PRC_TYPE_MKP_AnnotationItem)
+  SerializeContentPRCBase 
+  SerializeGraphics
+  SerializeReferenceUniqueIdentifier (markup)
+  SerializeUserData
+}
+
+void  PRCRepresentationItemContent::serializeRepresentationItemContent(PRCbitStream &pbs)
+{
+  SerializeContentPRCBase 
+  SerializeGraphics
+  WriteUnsignedInteger (index_local_coordinate_system + 1)
+  WriteUnsignedInteger (index_tessellation + 1)
+}
+
+void  PRCBrepModel::serializeBrepModel(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger (PRC_TYPE_RI_BrepModel)
+
+   SerializeRepresentationItemContent 
+   WriteBit (has_brep_data)
+   if (has_brep_data)
+   {
+      WriteUnsignedInteger (context_id+1)
+      WriteUnsignedInteger (body_id+1)
+   }
+   WriteBoolean (is_closed)
+   SerializeUserData
+}
+
+void  PRCPolyBrepModel::serializePolyBrepModel(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger (PRC_TYPE_RI_PolyBrepModel)
+
+   SerializeRepresentationItemContent 
+   WriteBoolean (is_closed)
+   SerializeUserData
+}
+
+void  PRCPointSet::serializePointSet(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_RI_PointSet)
+
+  SerializeRepresentationItemContent 
+
+  const uint32_t number_of_points = point.size();
+  WriteUnsignedInteger (number_of_points)
+  for (uint32_t i=0;i<number_of_points;i++)
+  {
+     SerializeVector3d (point[i])
+  }
+  SerializeUserData
+}
+
+void  PRCSet::serializeSet(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_RI_Set)
+
+  SerializeRepresentationItemContent 
+
+  const uint32_t number_of_elements = elements.size();
+  WriteUnsignedInteger (number_of_elements)
+  for (uint32_t i=0;i<number_of_elements;i++)
+  {
+    SerializeRepresentationItem (elements[i])
+  }
+  SerializeUserData
+}
+
+uint32_t PRCSet::addBrepModel(PRCBrepModel*& pBrepModel)
+{
+  elements.push_back(pBrepModel);
+  pBrepModel = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel)
+{
+  elements.push_back(pPolyBrepModel);
+  pPolyBrepModel = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addPointSet(PRCPointSet*& pPointSet)
+{
+  elements.push_back(pPointSet);
+  pPointSet  = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addSet(PRCSet*& pSet)
+{
+  elements.push_back(pSet);
+  pSet = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addWire(PRCWire*& pWire)
+{
+  elements.push_back(pWire);
+  pWire = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addPolyWire(PRCPolyWire*& pPolyWire)
+{
+  elements.push_back(pPolyWire);
+  pPolyWire = NULL;
+  return elements.size()-1;
+}
+
+uint32_t PRCSet::addRepresentationItem(PRCRepresentationItem*& pRepresentationItem)
+{
+  elements.push_back(pRepresentationItem);
+  pRepresentationItem = NULL;
+  return elements.size()-1;
+}
+
+void  PRCWire::serializeWire(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger (PRC_TYPE_RI_Curve)
+
+   SerializeRepresentationItemContent 
+   WriteBit (has_wire_body)
+   if (has_wire_body)
+   {
+      WriteUnsignedInteger (context_id+1)
+      WriteUnsignedInteger (body_id+1)
+   }
+
+   SerializeUserData
+}
+
+void  PRCPolyWire::serializePolyWire(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_RI_PolyWire)
+
+  SerializeRepresentationItemContent 
+  SerializeUserData
+}
+
+void  PRCGeneralTransformation3d::serializeGeneralTransformation3d(PRCbitStream &pbs) const
+{
+  WriteUnsignedInteger (PRC_TYPE_MISC_GeneralTransformation)
+  for (uint32_t i=0; i<16; i++)
+     WriteDouble(m_coef[i]); 
+}
+
+void  PRCCartesianTransformation3d::serializeCartesianTransformation3d(PRCbitStream &pbs) const
+{
+  WriteUnsignedInteger (PRC_TYPE_MISC_CartesianTransformation)
+  WriteCharacter ( behaviour )
+  if (behaviour & PRC_TRANSFORMATION_Translate)
+     SerializeVector3d ( origin )
+  if (behaviour & PRC_TRANSFORMATION_NonOrtho)
+  {
+     SerializeVector3d ( X )
+     SerializeVector3d ( Y )
+     SerializeVector3d ( Z )
+  }
+  else if (behaviour & PRC_TRANSFORMATION_Rotate)
+  {
+     SerializeVector3d ( X )
+     SerializeVector3d ( Y )
+  }
+
+  if (behaviour & PRC_TRANSFORMATION_NonUniformScale)
+  {
+        SerializeVector3d ( scale )
+  }
+  else if (behaviour & PRC_TRANSFORMATION_Scale)
+  {
+        WriteDouble ( uniform_scale )
+  }
+
+  if (behaviour & PRC_TRANSFORMATION_Homogeneous)
+  {
+     WriteDouble ( X_homogeneous_coord )
+     WriteDouble ( Y_homogeneous_coord )
+     WriteDouble ( Z_homogeneous_coord )
+     WriteDouble ( origin_homogeneous_coord )
+  }
+}
+
+void  PRCTransformation::serializeTransformation(PRCbitStream &pbs)
+{ 
+   WriteBit ( has_transformation )
+   if (has_transformation)
+   {
+      WriteCharacter ( behaviour )
+      if ( geometry_is_2D )
+      {
+         if (behaviour & PRC_TRANSFORMATION_Translate)
+            SerializeVector2d ( origin )
+         if (behaviour & PRC_TRANSFORMATION_Rotate)
+         {
+            SerializeVector2d ( x_axis )
+            SerializeVector2d ( y_axis )
+         }
+         if (behaviour & PRC_TRANSFORMATION_Scale)
+            WriteDouble ( scale )
+      }
+      else
+      {
+         if (behaviour & PRC_TRANSFORMATION_Translate)
+            SerializeVector3d ( origin )
+         if (behaviour & PRC_TRANSFORMATION_Rotate)
+         {
+            SerializeVector3d ( x_axis )
+            SerializeVector3d ( y_axis )
+         }
+         if (behaviour & PRC_TRANSFORMATION_Scale)
+            WriteDouble ( scale )
+      }
+   }
+}
+void  PRCCoordinateSystem::serializeCoordinateSystem(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger (PRC_TYPE_RI_CoordinateSystem)
+
+  SerializeRepresentationItemContent 
+  axis_set->serializeTransformation3d(pbs);
+  SerializeUserData
+}
+
+void  PRCFontKeysSameFont::serializeFontKeysSameFont(PRCbitStream &pbs)
+{
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteString (font_name)
+  WriteUnsignedInteger (char_set)
+  const uint32_t number_of_font_keys = font_keys.size();
+  WriteUnsignedInteger (number_of_font_keys)
+  for (i=0;i<number_of_font_keys;i++)
+  {
+     WriteUnsignedInteger (font_keys[i].font_size + 1)
+     WriteCharacter (font_keys[i].attributes)
+  }
+}
+
+void SerializeArrayRGBA (const std::vector<uint8_t> &rgba_vertices,const bool is_rgba, PRCbitStream &pbs)
+{
+  uint32_t i = 0;
+  uint32_t j = 0;
+// number_by_vector can be assigned a value of 3 (RGB) or 4 (RGBA).
+// number_of_vectors is equal to number_of_colors / number_by_vector.
+  const uint32_t number_by_vector=is_rgba?4:3;
+  const std::vector<uint8_t> &vector_color = rgba_vertices;
+  const uint32_t number_of_colors=vector_color.size();
+  const uint32_t number_of_vectors=number_of_colors / number_by_vector;
+  // first one 
+  for (i=0;i<number_by_vector;i++)
+     WriteCharacter (vector_color[i])
+  
+  for (i=1;i<number_of_vectors;i++)
+  {
+     bool b_same = true;
+     for (j=0;j<number_by_vector;j++)
+     {
+        if ((vector_color[i*number_by_vector+j] - vector_color[(i-1)*number_by_vector+j]) != 0)
+        {
+           b_same = false;
+           break;
+        }
+     }
+     WriteBoolean (b_same)
+     if (!b_same)
+     {
+        for (j=0;j<number_by_vector;j++)
+           WriteCharacter (vector_color[i*number_by_vector+j])
+     }
+  }
+}
+
+void  PRCTessFace::serializeTessFace(PRCbitStream &pbs)
+{
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteUnsignedInteger (PRC_TYPE_TESS_Face)
+
+  const uint32_t size_of_line_attributes=line_attributes.size();
+  WriteUnsignedInteger (size_of_line_attributes) 
+  for (i=0;i<size_of_line_attributes;i++) 
+     SerializeLineAttr (line_attributes[i])
+
+  WriteUnsignedInteger (start_wire) 
+  const uint32_t size_of_sizes_wire=sizes_wire.size();
+  WriteUnsignedInteger (size_of_sizes_wire) 
+  for (i=0;i<size_of_sizes_wire;i++) 
+     WriteUnsignedInteger (sizes_wire[i])
+
+  WriteUnsignedInteger (used_entities_flag) 
+
+  WriteUnsignedInteger (start_triangulated) 
+  const uint32_t size_of_sizes_triangulated=sizes_triangulated.size();
+  WriteUnsignedInteger (size_of_sizes_triangulated) 
+  for (i=0;i<size_of_sizes_triangulated;i++) 
+     WriteUnsignedInteger (sizes_triangulated[i])
+
+  if(number_of_texture_coordinate_indexes==0 &&
+     used_entities_flag &
+     (
+      PRC_FACETESSDATA_PolyfaceTextured|
+      PRC_FACETESSDATA_TriangleTextured|
+      PRC_FACETESSDATA_TriangleFanTextured|
+      PRC_FACETESSDATA_TriangleStripeTextured|
+      PRC_FACETESSDATA_PolyfaceOneNormalTextured|
+      PRC_FACETESSDATA_TriangleOneNormalTextured|
+      PRC_FACETESSDATA_TriangleFanOneNormalTextured|
+      PRC_FACETESSDATA_TriangleStripeOneNormalTextured
+     ))
+    WriteUnsignedInteger (1)  // workaround for error of not setting number_of_texture_coordinate_indexes
+  else 
+    WriteUnsignedInteger (number_of_texture_coordinate_indexes)
+
+  const bool has_vertex_colors = !rgba_vertices.empty();
+  WriteBoolean (has_vertex_colors)
+  if (has_vertex_colors)
+  {
+     WriteBoolean (is_rgba)
+     const bool b_optimised=false;
+     WriteBoolean (b_optimised)
+     if (!b_optimised)
+     {
+       SerializeArrayRGBA (rgba_vertices, is_rgba, pbs);
+     }
+     else
+     {
+     // not described
+     }
+  }
+  if (size_of_line_attributes) 
+     WriteUnsignedInteger (behaviour)
+}
+
+void  PRCContentBaseTessData::serializeContentBaseTessData(PRCbitStream &pbs)
+{
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteBoolean (is_calculated)
+  const uint32_t number_of_coordinates = coordinates.size();
+  WriteUnsignedInteger (number_of_coordinates)
+  for (i=0;i<number_of_coordinates;i++)
+     WriteDouble (coordinates[i])
+}
+
+void  PRC3DTess::serialize3DTess(PRCbitStream &pbs)
+{
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteUnsignedInteger (PRC_TYPE_TESS_3D)
+  SerializeContentBaseTessData 
+  WriteBoolean (has_faces)
+  WriteBoolean (has_loops)
+  const bool must_recalculate_normals=normal_coordinate.empty();
+  WriteBoolean (must_recalculate_normals)
+  if (must_recalculate_normals)
+  {
+     const uint8_t normals_recalculation_flags=0;
+     // not used; should be zero
+     WriteCharacter (normals_recalculation_flags)
+     // definition similar to VRML
+     WriteDouble (crease_angle)
+  }
+  
+  const uint32_t number_of_normal_coordinates=normal_coordinate.size();
+  WriteUnsignedInteger (number_of_normal_coordinates)
+  for (i=0;i<number_of_normal_coordinates;i++)
+     WriteDouble (normal_coordinate[i])
+  
+  const uint32_t number_of_wire_indices=wire_index.size();
+  WriteUnsignedInteger (number_of_wire_indices)
+  for (i=0;i<number_of_wire_indices;i++)
+     WriteUnsignedInteger (wire_index[i])
+  
+  // note : those can be single triangles, triangle fans or stripes
+  const uint32_t number_of_triangulated_indices=triangulated_index.size();
+  WriteUnsignedInteger (number_of_triangulated_indices)
+  for (i=0;i<number_of_triangulated_indices;i++)
+     WriteUnsignedInteger (triangulated_index[i])
+  
+  const uint32_t number_of_face_tessellation=face_tessellation.size();
+  WriteUnsignedInteger (number_of_face_tessellation)
+  for (i=0;i<number_of_face_tessellation;i++)
+     SerializeTessFace (face_tessellation[i])
+  
+  const uint32_t number_of_texture_coordinates=texture_coordinate.size();
+  WriteUnsignedInteger (number_of_texture_coordinates)
+  for (i=0;i<number_of_texture_coordinates;i++)
+     WriteDouble (texture_coordinate[i])
+}
+
+void PRC3DTess::addTessFace(PRCTessFace*& pTessFace)
+{
+  face_tessellation.push_back(pTessFace);
+  pTessFace = NULL;
+}
+
+void  PRC3DWireTess::serialize3DWireTess(PRCbitStream &pbs)
+{
+// group___tf3_d_wire_tess_data_____serialize2.html
+// group___tf3_d_wire_tess_data_____serialize_content2.html
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteUnsignedInteger (PRC_TYPE_TESS_3D_Wire)
+  SerializeContentBaseTessData 
+  const uint32_t number_of_wire_indexes=wire_indexes.size();
+  WriteUnsignedInteger (number_of_wire_indexes)
+  for (i=0;i<number_of_wire_indexes;i++)
+     WriteUnsignedInteger (wire_indexes[i])
+  
+  const bool has_vertex_colors = !rgba_vertices.empty();
+  WriteBoolean (has_vertex_colors)
+  if (has_vertex_colors)
+  {
+     WriteBoolean (is_rgba)
+     WriteBoolean (is_segment_color)
+     const bool b_optimised=false;
+     WriteBoolean (b_optimised)
+     if (!b_optimised)
+     {
+       SerializeArrayRGBA (rgba_vertices, is_rgba, pbs);
+     }
+     else
+     {
+     // not described
+     }
+  }
+}
+
+void  PRCMarkupTess::serializeMarkupTess(PRCbitStream &pbs)
+{
+// group___tf_markup_tess_data_____serialize2.html
+// group___tf_markup_tess_data_____serialize_content2.html
+  uint32_t i=0; // universal index for PRC standart compatibility
+  WriteUnsignedInteger (PRC_TYPE_TESS_Markup)
+  SerializeContentBaseTessData 
+
+  const uint32_t number_of_codes=codes.size();
+  WriteUnsignedInteger (number_of_codes)
+  for (i=0;i<number_of_codes;i++)
+     WriteUnsignedInteger (codes[i])
+  const uint32_t number_of_texts=texts.size();
+  WriteUnsignedInteger (number_of_texts)
+  for (i=0;i<number_of_texts;i++)
+     WriteString (texts[i])
+  WriteString (label) // label of tessellation
+  WriteCharacter (behaviour)
+}
+
+void PRCVector2d::serializeVector2d(PRCbitStream &pbs)
+{
+  WriteDouble (x)
+  WriteDouble (y)
+}
+
+uint32_t makeCADID()
+{
+  static uint32_t ID = 1;
+  return ID++;
+}
+
+uint32_t makePRCID()
+{
+  static uint32_t ID = 1;
+  return ID++;
+}
+
+bool type_eligible_for_reference(uint32_t type)
+{
+  if(
+     type == PRC_TYPE_MISC_EntityReference ||
+     type == PRC_TYPE_MISC_MarkupLinkedItem ||
+     type == PRC_TYPE_RI_BrepModel ||
+     type == PRC_TYPE_RI_Curve ||
+     type == PRC_TYPE_RI_Direction ||
+     type == PRC_TYPE_RI_Plane ||
+     type == PRC_TYPE_RI_PointSet ||
+     type == PRC_TYPE_RI_PolyBrepModel ||
+     type == PRC_TYPE_RI_PolyWire ||
+     type == PRC_TYPE_RI_Set ||
+     type == PRC_TYPE_RI_CoordinateSystem ||
+     type == PRC_TYPE_ASM_ProductOccurence ||
+     type == PRC_TYPE_ASM_PartDefinition ||
+     type == PRC_TYPE_ASM_Filter ||
+     type == PRC_TYPE_MKP_View ||
+     type == PRC_TYPE_MKP_Markup ||
+     type == PRC_TYPE_MKP_Leader ||
+     type == PRC_TYPE_MKP_AnnotationItem ||
+     type == PRC_TYPE_MKP_AnnotationSet ||
+     type == PRC_TYPE_MKP_AnnotationReference ||
+     type == PRC_TYPE_GRAPH_Style ||
+     type == PRC_TYPE_GRAPH_Material ||
+     type == PRC_TYPE_GRAPH_TextureApplication ||
+     type == PRC_TYPE_GRAPH_TextureDefinition ||
+     type == PRC_TYPE_GRAPH_LinePattern ||
+     type == PRC_TYPE_GRAPH_DottingPattern ||
+     type == PRC_TYPE_GRAPH_HatchingPattern ||
+     type == PRC_TYPE_GRAPH_SolidPattern ||
+     type == PRC_TYPE_GRAPH_VPicturePattern ||
+     type == PRC_TYPE_GRAPH_AmbientLight ||
+     type == PRC_TYPE_GRAPH_PointLight ||
+     type == PRC_TYPE_GRAPH_DirectionalLight ||
+     type == PRC_TYPE_GRAPH_SpotLight ||
+     type == PRC_TYPE_GRAPH_SceneDisplayParameters ||
+     type == PRC_TYPE_GRAPH_Camera
+    )
+    return true;
+  else
+    return false;
+}
+
+void writeUnit(PRCbitStream &out,bool fromCAD,double unit)
+{
+  out << fromCAD << unit;
+}
+
+void writeEmptyMarkups(PRCbitStream &out)
+{
+  out << (uint32_t)0 // # of linked items
+      << (uint32_t)0 // # of leaders
+      << (uint32_t)0 // # of markups
+      << (uint32_t)0; // # of annotation entities
+}
+
+void PRCBaseTopology::serializeBaseTopology(PRCbitStream &pbs)
+{
+   WriteBoolean (base_information)
+   if (base_information)
+   {
+      SerializeAttributeData
+      SerializeName (name)
+      WriteUnsignedInteger (identifier)
+   }
+}
+
+void PRCBaseGeometry::serializeBaseGeometry(PRCbitStream &pbs)
+{
+   WriteBoolean (base_information)
+   if (base_information)
+   {
+      SerializeAttributeData
+      SerializeName (name)
+      WriteUnsignedInteger (identifier)
+   }
+}
+
+void PRCContentBody::serializeContentBody(PRCbitStream &pbs)
+{
+   SerializeBaseTopology
+   WriteCharacter ( behavior )
+}
+
+void PRCBoundingBox::serializeBoundingBox(PRCbitStream &pbs)
+{
+   SerializeVector3d ( min )
+   SerializeVector3d ( max )
+}
+
+void PRCDomain::serializeDomain(PRCbitStream &pbs)
+{
+   SerializeVector2d ( min )
+   SerializeVector2d ( max )
+}
+
+void PRCInterval::serializeInterval(PRCbitStream &pbs)
+{
+   WriteDouble ( min )
+   WriteDouble ( max )
+}
+
+void PRCParameterization::serializeParameterization(PRCbitStream &pbs)
+{
+   SerializeInterval ( interval )
+   WriteDouble ( parameterization_coeff_a )
+   WriteDouble ( parameterization_coeff_b )
+}
+
+void PRCUVParameterization::serializeUVParameterization(PRCbitStream &pbs)
+{
+   WriteBoolean ( swap_uv )
+   SerializeDomain ( uv_domain )
+   WriteDouble ( parameterization_on_u_coeff_a )
+   WriteDouble ( parameterization_on_v_coeff_a )
+   WriteDouble ( parameterization_on_u_coeff_b )
+   WriteDouble ( parameterization_on_v_coeff_b )
+}
+
+void PRCContentSurface::serializeContentSurface(PRCbitStream &pbs)
+{
+   SerializeBaseGeometry
+   WriteUnsignedInteger ( extend_info )
+}
+
+void  PRCNURBSSurface::serializeNURBSSurface(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+//  uint32_t i=0, j=0;
+   WriteUnsignedInteger (PRC_TYPE_SURF_NURBS) 
+
+   SerializeContentSurface 
+   WriteBoolean ( is_rational )
+   WriteUnsignedInteger ( degree_in_u )
+   WriteUnsignedInteger ( degree_in_v )
+   const uint32_t highest_index_of_knots_in_u = knot_u.size()-1;
+   const uint32_t highest_index_of_knots_in_v = knot_v.size()-1;
+   const uint32_t highest_index_of_control_point_in_u = highest_index_of_knots_in_u - degree_in_u - 1;
+   const uint32_t highest_index_of_control_point_in_v = highest_index_of_knots_in_v - degree_in_v - 1;
+   WriteUnsignedInteger ( highest_index_of_control_point_in_u )
+   WriteUnsignedInteger ( highest_index_of_control_point_in_v )
+   WriteUnsignedInteger ( highest_index_of_knots_in_u )
+   WriteUnsignedInteger ( highest_index_of_knots_in_v )
+   for (i=0; i < (highest_index_of_control_point_in_u+1)*(highest_index_of_control_point_in_v+1); i++)
+   {
+      WriteDouble ( control_point[i].x )
+      WriteDouble ( control_point[i].y )
+      WriteDouble ( control_point[i].z )
+      if (is_rational)
+         WriteDouble ( control_point[i].w )
+   }
+//  for (i=0; i<=highest_index_of_control_point_in_u; i++)
+//  {
+//     for (j=0; j<=highest_index_of_control_point_in_v; j++)
+//     {
+//        WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].x )
+//        WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].y )
+//        WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].z )
+//        if (is_rational)
+//           WriteDouble ( control_point[i*(highest_index_of_control_point_in_u+1)+j].w )
+//     }
+//  }
+   for (i=0; i<=highest_index_of_knots_in_u; i++)
+      WriteDouble ( knot_u[i] )
+   for (i=0; i<=highest_index_of_knots_in_v; i++)
+      WriteDouble ( knot_v[i] )
+   WriteUnsignedInteger ( knot_type )
+   WriteUnsignedInteger ( surface_form )
+}
+
+void writeUnsignedIntegerWithVariableBitNumber(PRCbitStream &pbs, uint32_t value, uint32_t bit_number)
+{
+   uint32_t i;
+   for(i=0; i<bit_number; i++)
+   {
+      if( value >= 1u<<(bit_number - 1 - i) )
+      {
+         WriteBoolean (true)
+      
+         value -= 1u<<(bit_number - 1 - i);
+      }
+      else
+      {
+         WriteBoolean (false)
+      }
+   }
+}
+#define WriteUnsignedIntegerWithVariableBitNumber( value, bit_number )  writeUnsignedIntegerWithVariableBitNumber( pbs, (value), (bit_number) );
+
+void writeIntegerWithVariableBitNumber(PRCbitStream &pbs, int32_t iValue, uint32_t uBitNumber)
+{ 
+  WriteBoolean(iValue<0);
+  WriteUnsignedIntegerWithVariableBitNumber(abs(iValue), uBitNumber - 1);
+}
+#define WriteIntegerWithVariableBitNumber( value, bit_number )  writeIntegerWithVariableBitNumber( pbs, (value), (bit_number) );
+
+void writeDoubleWithVariableBitNumber(PRCbitStream &pbs, double dValue,double dTolerance, unsigned uBitNumber)
+{
+// calling functions must ensure no overflow
+  int32_t iTempValue = (int32_t) ( dValue / dTolerance );
+  WriteIntegerWithVariableBitNumber(iTempValue, uBitNumber);
+}
+#define WriteDoubleWithVariableBitNumber( value, bit_number )  writeDoubleWithVariableBitNumber( pbs, (value), (bit_number) );
+
+uint32_t  GetNumberOfBitsUsedToStoreUnsignedInteger(uint32_t uValue)
+{
+  uint32_t uNbBit=2;
+  uint32_t uTemp = 2;
+  while(uValue >= uTemp)
+  {
+    uTemp*=2;
+    uNbBit++;
+  }
+  return uNbBit-1;
+}
+
+void  writeNumberOfBitsThenUnsignedInteger(PRCbitStream &pbs, uint32_t unsigned_integer)
+{
+   uint32_t number_of_bits = GetNumberOfBitsUsedToStoreUnsignedInteger( unsigned_integer );
+   WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits, 5 )
+   WriteUnsignedIntegerWithVariableBitNumber ( unsigned_integer, number_of_bits )
+}
+#define WriteNumberOfBitsThenUnsignedInteger( value ) writeNumberOfBitsThenUnsignedInteger( pbs, value );
+
+uint32_t  GetNumberOfBitsUsedToStoreInteger(int32_t iValue)
+{
+   return GetNumberOfBitsUsedToStoreUnsignedInteger(abs(iValue))+1;
+}
+
+int32_t intdiv(double dValue, double dTolerance)
+{
+  double ratio=fabs(dValue)/dTolerance;
+  assert(ratio <= INT_MAX);
+  int32_t iTempValue=(int32_t) ratio;
+  if(ratio - iTempValue >= 0.5) iTempValue++;
+  if(dValue < 0) 
+    return -iTempValue;
+  else
+    return iTempValue;
+}
+
+// round dValue to nearest multiple of dTolerance
+double roundto(double dValue, double dTolerance)
+{
+    return intdiv(dValue, dTolerance) * dTolerance;
+}
+
+PRCVector3d roundto(PRCVector3d vec, double dTolerance)
+{
+    PRCVector3d res;
+    res.x = roundto(vec.x,dTolerance);
+    res.y = roundto(vec.y,dTolerance);
+    res.z = roundto(vec.z,dTolerance);
+    return    res;
+}
+
+uint32_t  GetNumberOfBitsUsedToStoreDouble(double dValue, double dTolerance )
+{
+   return GetNumberOfBitsUsedToStoreInteger(intdiv(dValue,dTolerance));
+}
+
+struct itriple
+{
+  int32_t x;
+  int32_t y;
+  int32_t z;
+};
+
+uint32_t  GetNumberOfBitsUsedToStoreTripleInteger(const itriple &iTriple)
+{
+   const uint32_t x_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.x);
+   const uint32_t y_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.y);
+   const uint32_t z_bits = GetNumberOfBitsUsedToStoreInteger(iTriple.z);
+   uint32_t bits = x_bits;
+   if(y_bits > bits)
+     bits = y_bits;
+   if(z_bits > bits)
+     bits = z_bits;
+   return bits;
+}
+
+itriple iroundto(PRCVector3d vec, double dTolerance)
+{
+    itriple res;
+    res.x = intdiv(vec.x, dTolerance);
+    res.y = intdiv(vec.y, dTolerance);
+    res.z = intdiv(vec.z, dTolerance);
+    return    res;
+}
+
+void  PRCCompressedFace::serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+   serializeCompressedAnaNurbs( pbs, brep_data_compressed_tolerance );
+}
+#define SerializeCompressedFace( value ) (value)->serializeCompressedFace( pbs, brep_data_compressed_tolerance );
+
+void  PRCCompressedFace::serializeContentCompressedFace(PRCbitStream &pbs)
+{
+   WriteBoolean ( orientation_surface_with_shell )
+   const bool surface_is_trimmed = false;
+   WriteBoolean ( surface_is_trimmed )
+}
+
+void  PRCCompressedFace::serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+   // WriteCompressedEntityType ( PRC_HCG_AnaNurbs )
+   const bool is_a_curve = false;
+   WriteBoolean ( is_a_curve ) 
+   WriteUnsignedIntegerWithVariableBitNumber (13 , 4)
+   serializeContentCompressedFace( pbs );
+   serializeCompressedNurbs( pbs, brep_data_compressed_tolerance );
+}
+
+void  PRCCompressedFace::serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance)
+{
+   const double nurbs_tolerance = 0.2*brep_data_compressed_tolerance;
+   const uint32_t degree_in_u = degree;
+   const uint32_t degree_in_v = degree;
+   
+   WriteUnsignedIntegerWithVariableBitNumber ( degree_in_u, 5)
+   WriteUnsignedIntegerWithVariableBitNumber ( degree_in_v, 5)
+
+   const uint32_t number_of_knots_in_u = 4; // 0011 or 00001111 knot vector - just 2 spans
+   WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_u - 2, 16)
+   uint32_t number_bit = degree_in_u ? Log2( degree_in_u + 2 ) : 2;
+   WriteBoolean (false) // Multiplicity_is_already_stored - no
+   WriteUnsignedIntegerWithVariableBitNumber( degree_in_u+1,number_bit)
+   WriteBoolean (true) // Multiplicity_is_already_stored - yes
+   const uint32_t number_of_knots_in_v = 4; // 0011 or 00001111 knot vector - just 2 spans
+   WriteUnsignedIntegerWithVariableBitNumber (number_of_knots_in_v - 2, 16)
+   number_bit = degree_in_v ? Log2( degree_in_v + 2 ) : 2;
+   WriteBoolean (false) // Multiplicity_is_already_stored - no
+   WriteUnsignedIntegerWithVariableBitNumber( degree_in_v+1,number_bit)
+   WriteBoolean (true) // Multiplicity_is_already_stored - yes
+  
+   const bool is_closed_u = false; 
+   WriteBoolean ( is_closed_u )
+   const bool is_closed_v = false; 
+   WriteBoolean ( is_closed_v )
+
+   const uint32_t number_of_control_point_in_u = degree_in_u + 1;
+   const uint32_t number_of_control_point_in_v = degree_in_v + 1;
+
+#if defined( __GNUC__ ) && !defined( __clang__ ) 
+   PRCVector3d P[number_of_control_point_in_u][number_of_control_point_in_v];
+#else
+   vector<vector<PRCVector3d> > P(number_of_control_point_in_u, vector<PRCVector3d>(number_of_control_point_in_v));
+#endif
+   for(uint32_t i=0;i<number_of_control_point_in_u;i++)
+   for(uint32_t j=0;j<number_of_control_point_in_v;j++)
+      P[i][j] = control_point[i*number_of_control_point_in_v+j];
+#ifdef __GNUC__
+   itriple compressed_control_point[number_of_control_point_in_u][number_of_control_point_in_v];
+   uint32_t control_point_type[number_of_control_point_in_u][number_of_control_point_in_v];
+#else
+   vector<vector<itriple> > compressed_control_point(number_of_control_point_in_u, vector<itriple>(number_of_control_point_in_v));
+   vector<vector<uint32_t> > control_point_type(number_of_control_point_in_u, vector<uint32_t>(number_of_control_point_in_v));
+#endif
+
+   uint32_t number_of_bits_for_isomin = 1;
+   uint32_t number_of_bits_for_rest = 1;
+   
+   for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+   {
+      compressed_control_point[0][j] = iroundto(P[0][j]-P[0][j-1], nurbs_tolerance );
+      P[0][j] = P[0][j-1] + roundto(P[0][j]-P[0][j-1], nurbs_tolerance);
+      uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[0][j]);
+      if (bit_size > number_of_bits_for_isomin)
+        number_of_bits_for_isomin = bit_size;
+   }
+
+   for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+   {
+      compressed_control_point[i][0] = iroundto(P[i][0]-P[i-1][0], nurbs_tolerance );
+      P[i][0] = P[i-1][0] + roundto(P[i][0]-P[i-1][0], nurbs_tolerance);
+      uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[i][0]);
+      if (bit_size > number_of_bits_for_isomin)
+        number_of_bits_for_isomin = bit_size;
+   }
+
+   for(uint32_t i=1;i<number_of_control_point_in_u;i++)
+   for(uint32_t j=1;j<number_of_control_point_in_v;j++)
+   {
+     compressed_control_point[i][j].x = 0;
+     compressed_control_point[i][j].y = 0;
+     compressed_control_point[i][j].z = 0;
+     
+     PRCVector3d V = P[i-1][j] - P[i-1][j-1];
+     PRCVector3d U = P[i][j-1] - P[i-1][j-1];
+     PRCVector3d Pc = P[i][j] - (P[i-1][j-1] + U + V);
+
+     if(Pc.Length() < nurbs_tolerance)
+     {
+       control_point_type[i][j] = 0;
+       P[i][j] = P[i-1][j-1] + U + V;
+     }
+     else 
+     {
+       PRCVector3d N = U*V;
+       PRCVector3d Ue = U;
+       PRCVector3d Ne = N;
+       if( V.Length() < FLT_EPSILON || !Ue.Normalize() || !Ne.Normalize())
+       {
+          control_point_type[i][j] = 3;
+       // Pc = roundto(Pc, nurbs_tolerance); // not sure if this rounding really happens, need to experiment, docs imply but do not state
+          compressed_control_point[i][j] = iroundto(Pc, nurbs_tolerance);
+          P[i][j] = P[i-1][j-1] + U + V + roundto(Pc, nurbs_tolerance); // see above
+       }
+       else
+       {
+         PRCVector3d NUe = Ne*Ue;
+         double x = Pc.Dot(Ue);
+         double y = Pc.Dot(NUe);
+         double z = Pc.Dot(Ne);
+
+         if(x*x+y*y<nurbs_tolerance*nurbs_tolerance)
+         {
+           control_point_type[i][j] = 1;
+           compressed_control_point[i][j] = iroundto(PRCVector3d(0.0,0.0,z), nurbs_tolerance);
+           P[i][j] = P[i-1][j-1] + U + V + roundto(z, nurbs_tolerance)*Ne; // see above
+         }
+         else
+         {
+           if(fabs(z)<nurbs_tolerance/2)
+           {
+             control_point_type[i][j] = 2;
+             compressed_control_point[i][j] = iroundto(PRCVector3d(x,y,0), nurbs_tolerance);
+             P[i][j] = P[i-1][j-1] + U + V + roundto(x, nurbs_tolerance)*Ue + roundto(y, nurbs_tolerance)*NUe; // see above
+           }
+           else
+           {
+             control_point_type[i][j] = 3;
+             compressed_control_point[i][j] = iroundto(Pc, nurbs_tolerance);
+             P[i][j] = P[i-1][j-1] + U + V + roundto(Pc, nurbs_tolerance); // see above
+           }
+         }
+       }
+     }
+     uint32_t bit_size = GetNumberOfBitsUsedToStoreTripleInteger(compressed_control_point[i][j]);
+     if (bit_size > number_of_bits_for_rest)
+       number_of_bits_for_rest = bit_size;
+   }
+
+   if( number_of_bits_for_rest == 2 ) number_of_bits_for_rest--; // really I think it must be unconditional, but so it seems to be done in Adobe Acrobat (9.3)
+   WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_isomin, 20 )
+   WriteUnsignedIntegerWithVariableBitNumber ( number_of_bits_for_rest,   20 )
+   WriteDouble ( P[0][0].x )
+   WriteDouble ( P[0][0].y )
+   WriteDouble ( P[0][0].z )
+   
+   for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+   {
+      WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].x, number_of_bits_for_isomin+1)
+      WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].y, number_of_bits_for_isomin+1)
+      WriteIntegerWithVariableBitNumber(compressed_control_point[0][j].z, number_of_bits_for_isomin+1)
+   }
+   
+   for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+   {
+      WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].x, number_of_bits_for_isomin+1)
+      WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].y, number_of_bits_for_isomin+1)
+      WriteIntegerWithVariableBitNumber(compressed_control_point[i][0].z, number_of_bits_for_isomin+1)
+   }
+   
+   for(uint32_t i = 1; i < number_of_control_point_in_u; i++)
+   {
+      for(uint32_t j = 1; j < number_of_control_point_in_v; j++)
+      {
+         WriteUnsignedIntegerWithVariableBitNumber ( control_point_type[i][j], 2 )
+         
+         if(control_point_type[i][j] == 1)
+         {
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 )
+         }
+         else if(control_point_type[i][j] == 2)
+         {
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 )
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 )
+         }
+         else if(control_point_type[i][j] == 3)
+         {
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].x, number_of_bits_for_rest+1 )
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].y, number_of_bits_for_rest+1 )
+            WriteIntegerWithVariableBitNumber ( compressed_control_point[i][j].z, number_of_bits_for_rest+1 )
+         }
+      }
+   }
+   
+   const uint32_t type_param_u = 0;
+   WriteBoolean( type_param_u == 0 )
+   const uint32_t type_param_v = 0;
+   WriteBoolean( type_param_v == 0 )
+   const bool is_rational = false;
+   WriteBoolean( is_rational )
+}
+
+void PRCCompressedBrepData::serializeCompressedShell(PRCbitStream &pbs)
+{
+   uint32_t i;
+   const uint32_t number_of_face = face.size();
+   WriteBoolean ( number_of_face == 1 )
+
+   if( number_of_face != 1 )
+      WriteNumberOfBitsThenUnsignedInteger (number_of_face)
+   
+   for( i=0; i < number_of_face; i++)
+         SerializeCompressedFace ( face[i] )
+   
+   const bool is_an_iso_face = false;
+   for( i=0; i < number_of_face; i++)
+      WriteBoolean ( is_an_iso_face )
+}
+
+void PRCCompressedBrepData::serializeCompressedBrepData(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger ( PRC_TYPE_TOPO_BrepDataCompress )
+   SerializeContentBody
+   
+   WriteDouble ( brep_data_compressed_tolerance )
+   const uint32_t number_of_bits_to_store_reference = 1;
+   WriteNumberOfBitsThenUnsignedInteger ( number_of_bits_to_store_reference )
+   const uint32_t number_vertex_iso = 0;
+   WriteUnsignedIntegerWithVariableBitNumber ( number_vertex_iso, number_of_bits_to_store_reference )
+   const uint32_t number_edge_iso = 0;
+   WriteUnsignedIntegerWithVariableBitNumber ( number_edge_iso, number_of_bits_to_store_reference )
+   
+   const uint32_t number_of_shell = 1;
+   const uint32_t number_of_connex = 1;
+   WriteBoolean ( number_of_shell == 1 && number_of_connex == 1 )
+   serializeCompressedShell( pbs );
+
+   uint32_t i;
+   const uint32_t number_of_faces = face.size();
+   for(i=0; i< number_of_faces; i++)
+      face[i]->serializeBaseTopology( pbs );
+}
+
+void  PRCBlend01::serializeBlend01(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Blend01) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   SerializePtrCurve ( center_curve ) 
+   SerializePtrCurve ( origin_curve ) 
+   SerializePtrCurve ( tangent_curve ) 
+}
+
+void  PRCRuled::serializeRuled(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Ruled) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   SerializePtrCurve ( first_curve ) 
+   SerializePtrCurve ( second_curve ) 
+}
+
+void  PRCSphere::serializeSphere(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Sphere) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   WriteDouble ( radius )
+}
+
+void  PRCCone::serializeCone(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Cone) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   WriteDouble ( bottom_radius )
+   WriteDouble ( semi_angle )
+}
+
+void  PRCCylinder::serializeCylinder(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Cylinder) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   WriteDouble ( radius )
+}
+
+void  PRCTorus::serializeTorus(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_SURF_Torus) 
+
+   SerializeContentSurface
+   SerializeTransformation
+   SerializeUVParameterization
+   WriteDouble ( major_radius )
+   WriteDouble ( minor_radius )
+}
+
+void PRCFace::serializeFace(PRCbitStream &pbs)
+{ 
+   uint32_t i = 0;
+   WriteUnsignedInteger (PRC_TYPE_TOPO_Face) 
+
+   SerializeBaseTopology
+   SerializePtrSurface ( base_surface )
+   WriteBit ( have_surface_trim_domain )
+   if ( have_surface_trim_domain )
+      SerializeDomain ( surface_trim_domain ) 
+   WriteBit ( have_tolerance )
+   if ( have_tolerance )
+      WriteDouble ( tolerance ) 
+   WriteUnsignedInteger ( number_of_loop )
+   WriteInteger ( outer_loop_index )
+   for (i=0;i<number_of_loop;i++)
+   {
+//    SerializePtrTopology ( loop[i] )
+   }
+}
+
+void PRCShell::serializeShell(PRCbitStream &pbs)
+{ 
+   uint32_t i = 0;
+   WriteUnsignedInteger (PRC_TYPE_TOPO_Shell) 
+
+   SerializeBaseTopology
+   WriteBoolean ( shell_is_closed )
+   uint32_t number_of_face = face.size();
+   WriteUnsignedInteger ( number_of_face ) 
+   for (i=0;i<number_of_face;i++)
+   {
+      SerializePtrTopology ( face[i] )
+      WriteCharacter ( orientation_surface_with_shell[i] )
+   }
+}
+
+void PRCShell::addFace(PRCFace*& pFace, uint8_t orientation)
+{
+  face.push_back(pFace);
+  pFace = NULL;
+  orientation_surface_with_shell.push_back(orientation);
+}
+
+void PRCConnex::serializeConnex(PRCbitStream &pbs)
+{ 
+   uint32_t i = 0;
+   WriteUnsignedInteger (PRC_TYPE_TOPO_Connex) 
+
+   SerializeBaseTopology
+   uint32_t number_of_shell = shell.size();
+   WriteUnsignedInteger ( number_of_shell ) 
+   for (i=0;i<number_of_shell;i++)
+   {
+      SerializePtrTopology ( shell[i] )
+   }
+}
+
+void PRCConnex::addShell(PRCShell*& pShell)
+{
+  shell.push_back(pShell);
+  pShell = NULL;
+}
+
+#define have_bbox( behavior ) (behavior!=0)
+void PRCBrepData::serializeBrepData(PRCbitStream &pbs)
+{
+   uint32_t i = 0;
+   WriteUnsignedInteger ( PRC_TYPE_TOPO_BrepData) 
+
+   SerializeContentBody 
+   uint32_t number_of_connex = connex.size();
+   WriteUnsignedInteger ( number_of_connex ) 
+   for ( i=0; i<number_of_connex; i++)
+   {
+      SerializePtrTopology ( connex[i] )
+   }
+   if ( have_bbox(behavior) )
+      SerializeBoundingBox
+}
+#undef have_bbox
+
+void PRCBrepData::addConnex(PRCConnex*& pConnex)
+{
+  connex.push_back(pConnex);
+  pConnex = NULL;
+}
+
+void PRCContentWireEdge::serializeContentWireEdge(PRCbitStream &pbs)
+{
+   SerializeBaseTopology
+   SerializePtrCurve ( curve_3d )
+   WriteBit ( has_curve_trim_interval )
+   if ( has_curve_trim_interval )
+      SerializeInterval ( curve_trim_interval )
+}
+
+void PRCWireEdge::serializeWireEdge(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger (PRC_TYPE_TOPO_WireEdge) 
+   SerializeContentWireEdge 
+}
+
+void PRCContentCurve::serializeContentCurve(PRCbitStream &pbs)
+{
+   SerializeBaseGeometry
+   WriteUnsignedInteger ( extend_info )
+   WriteBoolean ( is_3d )
+}
+
+void  PRCNURBSCurve::serializeNURBSCurve(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+   WriteUnsignedInteger (PRC_TYPE_CRV_NURBS) 
+
+   SerializeContentCurve 
+   WriteBoolean ( is_rational )
+   WriteUnsignedInteger ( degree )
+   uint32_t highest_index_of_control_point = control_point.size()-1;
+   uint32_t highest_index_of_knots = knot.size()-1;
+   WriteUnsignedInteger ( highest_index_of_control_point )
+   WriteUnsignedInteger ( highest_index_of_knots )
+   for (i=0; i<=highest_index_of_control_point; i++)
+   {
+      WriteDouble ( control_point[i].x )
+      WriteDouble ( control_point[i].y )
+      if (is_3d)
+         WriteDouble ( control_point[i].z )
+      if (is_rational)
+         WriteDouble ( control_point[i].w )
+   }
+   for (i=0; i<=highest_index_of_knots; i++)
+      WriteDouble ( knot[i] )
+   WriteUnsignedInteger ( knot_type )
+   WriteUnsignedInteger ( curve_form )
+}
+
+void  PRCPolyLine::serializePolyLine(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+   WriteUnsignedInteger (PRC_TYPE_CRV_PolyLine) 
+
+   SerializeContentCurve 
+   SerializeTransformation
+   SerializeParameterization
+   uint32_t number_of_point = point.size();
+   WriteUnsignedInteger ( number_of_point ) 
+   for (i=0; i<number_of_point; i++) 
+   {
+      if (is_3d)
+         SerializeVector3d ( point[i] )
+      else
+         SerializeVector2d ( point[i] )
+   }
+}
+
+void  PRCCircle::serializeCircle(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_CRV_Circle) 
+
+   SerializeContentCurve 
+   SerializeTransformation
+   SerializeParameterization
+   WriteDouble ( radius )
+}
+
+void  PRCComposite::serializeComposite(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+   WriteUnsignedInteger (PRC_TYPE_CRV_Composite) 
+
+   SerializeContentCurve 
+   SerializeTransformation
+   SerializeParameterization
+   uint32_t number_of_curves = base_curve.size();
+   WriteUnsignedInteger ( number_of_curves ) 
+   for (i=0; i<number_of_curves; i++) 
+   {
+      SerializePtrCurve ( base_curve[i] )
+      WriteBoolean ( base_sense[i] )
+   }
+   WriteBoolean ( is_closed )
+}
+
+void PRCTopoContext::serializeTopoContext(PRCbitStream &pbs)
+{ 
+   WriteUnsignedInteger (PRC_TYPE_TOPO_Context) 
+
+   SerializeContentPRCBase
+   WriteCharacter ( behaviour )
+   WriteDouble ( granularity )
+   WriteDouble ( tolerance )
+   WriteBoolean ( have_smallest_face_thickness )
+   if ( have_smallest_face_thickness )
+      WriteDouble ( smallest_thickness )
+   WriteBoolean ( have_scale )
+   if ( have_scale )
+      WriteDouble ( scale )
+}
+
+void PRCTopoContext::serializeContextAndBodies(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+   SerializeTopoContext 
+   uint32_t number_of_bodies = body.size();
+   WriteUnsignedInteger (number_of_bodies) 
+   for (i=0;i<number_of_bodies;i++) 
+      SerializeBody (body[i]) 
+}
+
+void PRCTopoContext::serializeGeometrySummary(PRCbitStream &pbs)
+{ 
+   uint32_t i=0;
+   uint32_t number_of_bodies = body.size();
+   WriteUnsignedInteger (number_of_bodies) 
+   for (i=0;i<number_of_bodies;i++) 
+   {
+      WriteUnsignedInteger ( body[i]->serialType() ) 
+      if ( IsCompressedType(body[i]->serialType()) )
+      {
+         WriteDouble ( body[i]->serialTolerance() ) 
+      }
+   }
+}
+
+void PRCTopoContext::serializeContextGraphics(PRCbitStream &pbs)
+{ 
+   uint32_t i=0, j=0, k=0, l=0;
+   ResetCurrentGraphics
+   uint32_t number_of_body = body.size();
+   PRCGraphicsList element;
+   bool has_graphics = false;
+   for (i=0;i<number_of_body;i++)
+   {
+        if ( body[i]->topo_item_type == PRC_TYPE_TOPO_BrepData && dynamic_cast<PRCBrepData*>(body[i]))
+        {
+                PRCBrepData *body_i = dynamic_cast<PRCBrepData*>(body[i]);
+                for (j=0;j<body_i->connex.size();j++)
+                {
+                        for(k=0;k<body_i->connex[j]->shell.size();k++)
+                        {
+                                for( l=0;l<body_i->connex[j]->shell[k]->face.size();l++)
+                                {
+                                        element.push_back( body_i->connex[j]->shell[k]->face[l] );
+                                        has_graphics = has_graphics || body_i->connex[j]->shell[k]->face[l]->has_graphics();
+                                }
+                        }
+                }
+        }
+        else if ( body[i]->topo_item_type == PRC_TYPE_TOPO_BrepDataCompress && dynamic_cast<PRCCompressedBrepData*>(body[i]))
+        {
+                PRCCompressedBrepData *body_i = dynamic_cast<PRCCompressedBrepData*>(body[i]);
+               for( l=0;l<body_i->face.size();l++)
+               {
+                       element.push_back( body_i->face[l] );
+                       has_graphics = has_graphics || body_i->face[l]->has_graphics();
+               }
+        }
+   }
+   uint32_t number_of_treat_type = 0;
+   if (has_graphics && !element.empty())
+     number_of_treat_type = 1;
+   WriteUnsignedInteger (number_of_treat_type) 
+   for (i=0;i<number_of_treat_type;i++) 
+   {
+      const uint32_t element_type = PRC_TYPE_TOPO_Face;
+      WriteUnsignedInteger (element_type) 
+      const uint32_t number_of_element = element.size();
+      WriteUnsignedInteger (number_of_element) 
+      for (j=0;j<number_of_element;j++) 
+      {
+         WriteBoolean ( element[j]->has_graphics() ) 
+         if (element[j]->has_graphics()) 
+         {
+            element[j]->serializeGraphics(pbs);
+         }
+      }
+   }
+}
+
+uint32_t PRCTopoContext::addSingleWireBody(PRCSingleWireBody*& pSingleWireBody)
+{
+  body.push_back(pSingleWireBody);
+  pSingleWireBody = NULL;
+  return body.size()-1;
+}
+
+uint32_t PRCTopoContext::addBrepData(PRCBrepData*& pBrepData)
+{
+  body.push_back(pBrepData);
+  pBrepData = NULL;
+  return body.size()-1;
+}
+
+uint32_t PRCTopoContext::addCompressedBrepData(PRCCompressedBrepData*& pCompressedBrepData)
+{
+  body.push_back(pCompressedBrepData);
+  pCompressedBrepData = NULL;
+  return body.size()-1;
+}
+
+void PRCSingleWireBody::serializeSingleWireBody(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger ( PRC_TYPE_TOPO_SingleWireBody) 
+
+  SerializeContentBody 
+  SerializePtrTopology ( wire_edge )
+}
+
+void PRCUniqueId::serializeCompressedUniqueId(PRCbitStream &pbs) const
+{
+   WriteUnsignedInteger (id0) 
+   WriteUnsignedInteger (id1) 
+   WriteUnsignedInteger (id2) 
+   WriteUnsignedInteger (id3)  
+}
+
+void PRCUniqueId::serializeFileStructureUncompressedUniqueId(std::ostream& out) const
+{
+   WriteUncompressedUnsignedInteger (id0) 
+   WriteUncompressedUnsignedInteger (id1) 
+   WriteUncompressedUnsignedInteger (id2) 
+   WriteUncompressedUnsignedInteger (id3) 
+}
+
+void PRCUnit::serializeUnit(PRCbitStream &pbs)
+{
+   WriteBoolean (unit_from_CAD_file)
+   WriteDouble (unit)
+}
+
+void PRCProductOccurrence::serializeProductOccurrence(PRCbitStream &pbs)
+{
+   WriteUnsignedInteger ( PRC_TYPE_ASM_ProductOccurence ) 
+
+   SerializePRCBaseWithGraphics 
+
+// SerializeReferencesOfProductOccurrence 
+   WriteUnsignedInteger (index_part+1)
+   WriteUnsignedInteger (index_prototype+1)
+   if (index_prototype != m1)
+   {
+      WriteBoolean (prototype_in_same_file_structure)
+      if (!prototype_in_same_file_structure)
+         SerializeCompressedUniqueId (prototype_file_structure)
+   }
+   WriteUnsignedInteger(index_external_data+1)
+   if (index_external_data != m1)
+   {
+      WriteBoolean (external_data_in_same_file_structure)
+      if (!external_data_in_same_file_structure)
+         SerializeCompressedUniqueId (external_data_file_structure)
+   }
+   const uint32_t number_of_son_product_occurrences = index_son_occurrence.size();
+   WriteUnsignedInteger (number_of_son_product_occurrences)
+   for (uint32_t i=0;i<number_of_son_product_occurrences;i++)
+      WriteUnsignedInteger (index_son_occurrence[i])
+
+   WriteCharacter (product_behaviour)
+
+// SerializeProductInformation (product_information)
+   SerializeUnit (unit_information)
+   WriteCharacter (product_information_flags)
+   WriteInteger (product_load_status)
+
+   const bool has_location = location != NULL;
+   WriteBit (has_location)
+   if (has_location)
+     location->serializeTransformation3d (pbs);
+   
+   WriteUnsignedInteger (0) // number_of_references
+   
+// SerializeMarkups (markups)
+   WriteUnsignedInteger (0) // number_of_linked_items 
+   WriteUnsignedInteger (0) // number_of_leaders 
+   WriteUnsignedInteger (0) // number_of_markups 
+   WriteUnsignedInteger (0) // number_of_annotation_entities 
+
+   
+   WriteUnsignedInteger (0) // number_of_views
+   WriteBit (false) // has_entity_filter
+   WriteUnsignedInteger (0) // number_of_display_filters
+   WriteUnsignedInteger (0) // number_of_scene_display_parameters
+
+   SerializeUserData
+}
+
+uint32_t PRCPartDefinition::addBrepModel(PRCBrepModel*& pBrepModel)
+{
+  representation_item.push_back(pBrepModel);
+  pBrepModel = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel)
+{
+  representation_item.push_back(pPolyBrepModel);
+  pPolyBrepModel = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPointSet(PRCPointSet*& pPointSet)
+{
+  representation_item.push_back(pPointSet);
+  pPointSet = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addSet(PRCSet*& pSet)
+{
+  representation_item.push_back(pSet);
+  pSet = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addWire(PRCWire*& pWire)
+{
+  representation_item.push_back(pWire);
+  pWire = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addPolyWire(PRCPolyWire*& pPolyWire)
+{
+  representation_item.push_back(pPolyWire);
+  pPolyWire = NULL;
+  return representation_item.size()-1;
+}
+
+uint32_t PRCPartDefinition::addRepresentationItem(PRCRepresentationItem*& pRepresentationItem)
+{
+  representation_item.push_back(pRepresentationItem);
+  pRepresentationItem = NULL;
+  return representation_item.size()-1;
+}
+
+void PRCPartDefinition::serializePartDefinition(PRCbitStream &pbs)
+{
+  WriteUnsignedInteger ( PRC_TYPE_ASM_PartDefinition ) 
+       
+  SerializePRCBaseWithGraphics
+  SerializeBoundingBox
+
+  uint32_t number_of_representation_items = representation_item.size();
+  WriteUnsignedInteger (number_of_representation_items)
+  for (uint32_t i=0;i<number_of_representation_items;i++)
+    SerializeRepresentationItem (representation_item[i])
+       
+  // SerializeMarkups (markups)
+  WriteUnsignedInteger (0) // number_of_linked_items 
+  WriteUnsignedInteger (0) // number_of_leaders 
+  WriteUnsignedInteger (0) // number_of_markups 
+  WriteUnsignedInteger (0) // number_of_annotation_entities 
+
+  WriteUnsignedInteger (0) // number_of_views
+  SerializeUserData
+}      
diff --git a/src/prc/writePRC.h b/src/prc/writePRC.h
new file mode 100644 (file)
index 0000000..5cb935c
--- /dev/null
@@ -0,0 +1,1476 @@
+/************
+*
+*   This file is part of a tool for producing 3D content in the PRC format.
+*   Copyright (C) 2008  Orest Shardt <shardtor (at) gmail dot com>
+*
+*   This program is free software: you can redistribute it and/or modify
+*   it under the terms of the GNU Lesser General Public License as published by
+*   the Free Software Foundation, either version 3 of the License, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Lesser General Public License for more details.
+*
+*   You should have received a copy of the GNU Lesser General Public License
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#ifndef __WRITE_PRC_H
+#define __WRITE_PRC_H
+#include <string>
+#include <vector>
+#include <deque>
+#include <list>
+#ifdef __GNUC__
+#include <ext/slist>
+#endif
+#include <map>
+#include <iostream>
+#include "PRCbitStream.h"
+#include "PRC.h"
+#include <float.h>
+#include <math.h>
+
+static const uint32_t m1=(uint32_t)-1;
+static const double pi=acos(-1.0);
+
+class PRCVector3d
+{
+public :
+ double x;
+ double y;
+ double z;
+ PRCVector3d() :
+ x(0), y(0), z(0) {}
+ PRCVector3d(double fx, double fy, double fz) :
+ x(fx), y(fy), z(fz) {}
+ PRCVector3d(const double c[], double fx=0, double fy=0, double fz=0) :
+ x(c?c[0]:fx), y(c?c[1]:fy), z(c?c[2]:fz) {}
+ PRCVector3d(const PRCVector3d& sVector3d) :
+ x(sVector3d.x), y(sVector3d.y), z(sVector3d.z) {}
+
+ void Set(double fx, double fy, double fz)
+ { x = fx; y = fy; z = fz; }
+ double Dot(const PRCVector3d & sPt) const
+ { return(x*sPt.x)+(y*sPt.y)+(z*sPt.z); }
+ double LengthSquared()
+ { return(x*x+y*y+z*z); }
+
+ friend PRCVector3d operator + (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d(a.x+b.x,a.y+b.y,a.z+b.z); }
+ friend PRCVector3d operator - (const PRCVector3d& a)
+ { return PRCVector3d(-a.x,-a.y,-a.z); }
+ friend PRCVector3d operator - (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d(a.x-b.x,a.y-b.y,a.z-b.z); }
+ friend PRCVector3d operator * (const PRCVector3d& a, const double d)
+ { return PRCVector3d(a.x*d,a.y*d,a.z*d); }
+ friend PRCVector3d operator * (const double d, const PRCVector3d& a)
+ { return PRCVector3d(a.x*d,a.y*d,a.z*d); }
+ friend PRCVector3d operator / (const PRCVector3d& a, const double d)
+ { return PRCVector3d(a.x/d,a.y/d,a.z/d); }
+ friend PRCVector3d operator * (const PRCVector3d& a, const PRCVector3d& b)
+ { return PRCVector3d((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x)); }
+
+ void write(PRCbitStream &out) { out << x << y << z; }
+ void serializeVector3d(PRCbitStream &pbs) const { pbs << x << y << z; }
+ void serializeVector2d(PRCbitStream &pbs) const { pbs << x << y; }
+
+ double Length();
+ bool Normalize();
+
+ bool operator==(const PRCVector3d &v) const
+ {
+  return x==v.x && y==v.y && z==v.z;
+ }
+ bool operator!=(const PRCVector3d &v) const
+ {
+  return !(x==v.x && y==v.y && z==v.z);
+ }
+ bool operator<(const PRCVector3d &v) const
+ {
+   if(x!=v.x)
+     return (x<v.x);
+   if(y!=v.y)
+     return (y<v.y);
+   return (z<v.z);
+ }
+ friend std::ostream& operator << (std::ostream& out, const PRCVector3d& v)
+ {
+   out << "(" << v.x << "," << v.y << "," << v.z << ")";
+   return out;
+ }
+};
+/*
+class UUID
+{
+  public:
+    UUID(uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) :
+      id0(u0),id1(u1),id2(u2),id3(u3) {}
+    void write(PRCbitStream &out)
+    {
+      out << id0 << id1 << id2 << id3;
+    }
+  private:
+    uint32_t id0,id1,id2,id3;
+}; */
+
+void writeUncompressedUnsignedInteger(std::ostream &out, uint32_t data);
+
+void writeUnit(PRCbitStream &,bool,double);
+
+void writeEmptyMarkups(PRCbitStream&);
+
+class UserData
+{
+  public:
+    UserData(uint32_t s = 0, uint8_t* d = 0) : size(s),data(d) {}
+    void write(PRCbitStream&);
+  private:
+    uint32_t size;
+    uint8_t* data;
+};
+
+struct PRCAttributeEntry
+{
+       PRCAttributeEntry() : title_is_integer(false) {}
+       PRCAttributeEntry(uint32_t integer) : title_is_integer(true)
+  {
+    title_integer = integer;
+  }
+       PRCAttributeEntry(const std::string &text) : title_is_integer(false)
+  {
+    title_text = text;
+  }
+  void serializeAttributeEntry(PRCbitStream&) const;
+  bool title_is_integer;
+  std::string title_text;
+  uint32_t title_integer;
+};
+
+class PRCSingleAttribute : public PRCAttributeEntry
+{
+  public:
+  PRCSingleAttribute() : type(KEPRCModellerAttributeTypeNull) {}
+       PRCSingleAttribute(int32_t integer) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeInt)
+  {
+    value.integer = integer;
+  }
+       PRCSingleAttribute(double real) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeReal)
+  {
+    value.real = real;
+  }
+  PRCSingleAttribute(uint32_t time) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeTime)
+  {
+    value.time = time;
+  }  
+       PRCSingleAttribute(const std::string &text) : PRCAttributeEntry(), type(KEPRCModellerAttributeTypeString)
+  {
+    value_text = text;}
+       PRCSingleAttribute(uint32_t title, int32_t integer) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeInt)
+  {
+    value.integer = integer;
+  }
+       PRCSingleAttribute(uint32_t title, double real) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeReal)
+  {
+    value.real = real;
+  }
+  PRCSingleAttribute(uint32_t title, uint32_t time) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeTime)
+  {
+    value.time = time;
+  }  
+       PRCSingleAttribute(uint32_t title, const std::string &text) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeString)
+  {
+    value_text = text;
+  }
+       PRCSingleAttribute(const std::string title, int32_t integer) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeInt)
+  {
+    value.integer = integer;
+  }
+       PRCSingleAttribute(const std::string title, double real) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeReal)
+  {
+    value.real = real;
+  }
+  PRCSingleAttribute(const std::string title, uint32_t time) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeTime)
+  {
+    value.time = time;
+  }  
+       PRCSingleAttribute(const std::string title, const std::string &text) : PRCAttributeEntry(title), type(KEPRCModellerAttributeTypeString)
+  {
+    value_text = text;
+  }
+  void serializeSingleAttribute(PRCbitStream&) const;
+  EPRCModellerAttributeType  type;
+  union PRCSingleAttributeData
+  {
+    int32_t integer;
+    double real;
+    uint32_t time;
+  } value;
+  std::string value_text;
+};
+
+class PRCAttribute : public PRCAttributeEntry
+{
+  public:
+  PRCAttribute() : PRCAttributeEntry() {}
+       PRCAttribute(uint32_t title) : PRCAttributeEntry(title) {}
+       PRCAttribute(const std::string title) : PRCAttributeEntry(title) {}
+  void serializeAttribute(PRCbitStream &) const;
+  PRCSingleAttribute& newKey() { attribute_keys.resize(attribute_keys.size()+1); return attribute_keys.back(); }
+  void addKey(const PRCSingleAttribute &key) { attribute_keys.push_back(key); }
+  std::deque<PRCSingleAttribute> attribute_keys;
+};
+#ifdef __GNUC__
+typedef __gnu_cxx::slist<PRCAttribute> PRCAttributeList;
+#else
+typedef std::list<PRCAttribute> PRCAttributeList;
+#endif
+
+class PRCAttributes
+{
+  public:
+  void serializeAttributes(PRCbitStream&) const;
+  PRCAttribute& newAttribute() { attributes.push_front(PRCAttribute()); return attributes.front(); }
+  void addAttribute(const PRCAttribute &attribute) { attributes.push_front(attribute); }
+  PRCAttributeList attributes;
+};
+
+bool type_eligible_for_reference(uint32_t type);
+uint32_t makeCADID();
+uint32_t makePRCID();
+
+class ContentPRCBase : public PRCAttributes
+{
+  public:
+  ContentPRCBase(uint32_t t, std::string n="") :
+    type(t),name(n),CAD_identifier(0), CAD_persistent_identifier(0), PRC_unique_identifier(0)
+  {
+    if(type_eligible_for_reference(type))
+    {
+      CAD_identifier = makeCADID();
+      PRC_unique_identifier = makePRCID();
+    }
+  }
+  void serializeContentPRCBase(PRCbitStream&) const;
+  uint32_t getPRCID() const { return PRC_unique_identifier; }
+  uint32_t getType() const { return type; }
+  uint32_t type;
+  std::string name;
+  uint32_t CAD_identifier, CAD_persistent_identifier, PRC_unique_identifier;
+};
+
+class PRCReferenceUniqueIdentifier
+{
+public:
+  PRCReferenceUniqueIdentifier() :
+    type(0), unique_identifier(m1) {}
+  void serializeReferenceUniqueIdentifier(PRCbitStream&);
+  uint32_t type;
+// bool reference_in_same_file_structure;
+// PRCUniqueId target_file_structure;
+  uint32_t unique_identifier;
+};
+
+extern std::string currentName;
+void writeName(PRCbitStream&,const std::string&);
+void resetName();
+
+extern uint32_t current_layer_index;
+extern uint32_t current_index_of_line_style;
+extern uint16_t current_behaviour_bit_field;
+
+void writeGraphics(PRCbitStream&,uint32_t=m1,uint32_t=m1,uint16_t=1,bool=false);
+void resetGraphics();
+
+void resetGraphicsAndName();
+
+struct PRCRgbColor
+{
+  PRCRgbColor(double r=0.0, double g=0.0, double b=0.0) :
+    red(r), green(g), blue(b) {}
+  double red,green,blue;
+  void serializeRgbColor(PRCbitStream&);
+
+  bool operator==(const PRCRgbColor &c) const
+  {
+    return (red==c.red && green==c.green && blue==c.blue);
+  }
+  bool operator!=(const PRCRgbColor &c) const
+  {
+    return !(red==c.red && green==c.green && blue==c.blue);
+  }
+  bool operator<(const PRCRgbColor &c) const
+  {
+    if(red!=c.red)
+      return (red<c.red);
+    if(green!=c.green)
+      return (green<c.green);
+    return (blue<c.blue);
+  }
+};
+
+class PRCPicture : public ContentPRCBase
+{
+public:
+  PRCPicture(std::string n="") :
+  ContentPRCBase(PRC_TYPE_GRAPH_Picture,n), format(KEPRCPicture_PNG), uncompressed_file_index(m1), pixel_width(0), pixel_height(0) {}
+  void serializePicture(PRCbitStream&);
+  EPRCPictureDataFormat format;
+  uint32_t uncompressed_file_index;
+  uint32_t pixel_width;
+  uint32_t pixel_height;
+};
+
+struct PRCVector2d
+{
+  PRCVector2d() :
+  x(0.0), y(0.0) {}
+  PRCVector2d(double X, double Y) :
+  x(X), y(Y) {}
+  void serializeVector2d(PRCbitStream&);
+  double x;
+  double y;
+  PRCVector2d(const double c[], double fx=0, double fy=0) :
+  x(c?c[0]:fx), y(c?c[1]:fy) {}
+  PRCVector2d(const PRCVector2d& sVector2d) :
+  x(sVector2d.x), y(sVector2d.y) {}
+  
+  void Set(double fx, double fy)
+  { x = fx; y = fy; }
+  double Dot(const PRCVector2d & sPt) const
+  { return(x*sPt.x)+(y*sPt.y); }
+  double LengthSquared()
+  { return(x*x+y*y); }
+  
+  friend PRCVector2d operator + (const PRCVector2d& a, const PRCVector2d& b)
+  { return PRCVector2d(a.x+b.x,a.y+b.y); }
+  friend PRCVector2d operator - (const PRCVector2d& a)
+  { return PRCVector2d(-a.x,-a.y); }
+  friend PRCVector2d operator - (const PRCVector2d& a, const PRCVector2d& b)
+  { return PRCVector2d(a.x-b.x,a.y-b.y); }
+  friend PRCVector2d operator * (const PRCVector2d& a, const double d)
+  { return PRCVector2d(a.x*d,a.y*d); }
+  friend PRCVector2d operator * (const double d, const PRCVector2d& a)
+  { return PRCVector2d(a.x*d,a.y*d); }
+  friend PRCVector2d operator / (const PRCVector2d& a, const double d)
+  { return PRCVector2d(a.x/d,a.y/d); }
+    
+  double Length();
+  bool Normalize();
+  
+  bool operator==(const PRCVector2d &v) const
+  {
+    return x==v.x && y==v.y;
+  }
+  bool operator!=(const PRCVector2d &v) const
+  {
+    return !(x==v.x && y==v.y);
+  }
+  bool operator<(const PRCVector2d &v) const
+  {
+    if(x!=v.x)
+      return (x<v.x);
+    return (y<v.y);
+  }
+  friend std::ostream& operator << (std::ostream& out, const PRCVector2d& v)
+  {
+    out << "(" << v.x << "," << v.y << ")";
+    return out;
+  }
+};
+
+class PRCTextureDefinition : public ContentPRCBase
+{
+public:
+  PRCTextureDefinition(std::string n="") :
+    ContentPRCBase(PRC_TYPE_GRAPH_TextureDefinition,n), picture_index(m1), texture_mapping_attribute(PRC_TEXTURE_MAPPING_DIFFUSE),
+    texture_mapping_attribute_intensity(1.0), texture_mapping_attribute_components(PRC_TEXTURE_MAPPING_COMPONENTS_RGBA),
+    texture_function(KEPRCTextureFunction_Modulate), texture_applying_mode(PRC_TEXTURE_APPLYING_MODE_NONE),
+    texture_wrapping_mode_S(KEPRCTextureWrappingMode_Unknown), texture_wrapping_mode_T(KEPRCTextureWrappingMode_Unknown) // ,
+    // texture_transformation(false), texture_flip_S(false), texture_flip_T(false),
+    // behaviour(PRC_TRANSFORMATION_Identity), scale(1.0,1.0), uniform_scale(1.0)
+    {}
+  void serializeTextureDefinition(PRCbitStream&);
+  uint32_t picture_index;
+  uint32_t texture_mapping_attribute;
+  double texture_mapping_attribute_intensity;
+  uint8_t texture_mapping_attribute_components;
+  EPRCTextureFunction texture_function;
+  uint8_t texture_applying_mode;
+  EPRCTextureWrappingMode texture_wrapping_mode_S;
+  EPRCTextureWrappingMode texture_wrapping_mode_T;
+  // bool texture_transformation;
+  // bool texture_flip_S;
+  // bool texture_flip_T;
+  // uint8_t behaviour;
+  // PRCVector2d origin;
+  // PRCVector2d X;
+  // PRCVector2d Y;
+  // PRCVector2d scale;
+  // double uniform_scale;
+  // double X_homegeneous_coord;
+  // double Y_homegeneous_coord;
+  // double origin_homegeneous_coord;
+};
+typedef std::deque <PRCTextureDefinition*>  PRCTextureDefinitionList;
+
+class PRCMaterial
+{
+public:
+  virtual ~PRCMaterial() {}
+  virtual void serializeMaterial(PRCbitStream&) = 0;
+};
+typedef std::deque <PRCMaterial*>  PRCMaterialList;
+
+class PRCMaterialGeneric : public ContentPRCBase, public PRCMaterial
+{
+public:
+  PRCMaterialGeneric(std::string n="") :
+    ContentPRCBase(PRC_TYPE_GRAPH_Material,n),
+    ambient(m1), diffuse(m1), emissive(m1), specular(m1), 
+    shininess(0.0),
+    ambient_alpha(1.0), diffuse_alpha(1.0), emissive_alpha(1.0), specular_alpha(1.0)
+    {}
+  void serializeMaterialGeneric(PRCbitStream&);
+  void serializeMaterial(PRCbitStream &pbs) { serializeMaterialGeneric(pbs); }
+  uint32_t picture_index;
+  uint32_t ambient;
+  uint32_t diffuse;
+  uint32_t emissive;
+  uint32_t specular;
+  double shininess;
+  double ambient_alpha;
+  double diffuse_alpha;
+  double emissive_alpha;
+  double specular_alpha;
+
+  bool operator==(const PRCMaterialGeneric &m) const
+  {
+    return (ambient==m.ambient && diffuse==m.diffuse && emissive==m.emissive && specular==m.specular && shininess==m.shininess &&
+            ambient_alpha==m.ambient_alpha && diffuse_alpha==m.diffuse_alpha && emissive_alpha==m.emissive_alpha && specular_alpha==m.specular_alpha);
+  }
+};
+
+class PRCTextureApplication : public ContentPRCBase, public PRCMaterial
+{
+public:
+  PRCTextureApplication(std::string n="") :
+    ContentPRCBase(PRC_TYPE_GRAPH_TextureApplication,n),
+    material_generic_index(m1), texture_definition_index(m1),
+    next_texture_index(m1), UV_coordinates_index(0)
+    {}
+  void serializeTextureApplication(PRCbitStream&);
+  void serializeMaterial(PRCbitStream &pbs) { serializeTextureApplication(pbs); }
+  uint32_t material_generic_index;
+  uint32_t texture_definition_index;
+  uint32_t next_texture_index;
+  uint32_t UV_coordinates_index;
+};
+
+class PRCLinePattern : public ContentPRCBase
+{
+public:
+  PRCLinePattern(std::string n="") :
+  ContentPRCBase(PRC_TYPE_GRAPH_LinePattern,n),
+  phase(0), is_real_length(false) {}
+  void serializeLinePattern(PRCbitStream&);
+  std::vector<double> lengths;
+  double phase;
+  bool is_real_length;
+};
+typedef std::deque <PRCLinePattern*>  PRCLinePatternList;
+
+class PRCStyle : public ContentPRCBase
+{
+public:
+  PRCStyle(std::string n="") :
+    ContentPRCBase(PRC_TYPE_GRAPH_Style,n), line_width(0.0), is_vpicture(false), line_pattern_vpicture_index(m1),
+    is_material(false), color_material_index(m1), is_transparency_defined(false), transparency(255), additional(0)
+    {}
+  void serializeCategory1LineStyle(PRCbitStream&);
+  double line_width;
+  bool is_vpicture;
+  uint32_t line_pattern_vpicture_index;
+  bool is_material;
+  uint32_t color_material_index;
+  bool is_transparency_defined;
+  uint8_t transparency;
+  uint8_t additional;
+};
+typedef std::deque <PRCStyle*>  PRCStyleList;
+
+class PRCTessFace
+{
+public:
+  PRCTessFace() :
+  start_wire(0), used_entities_flag(0),
+  start_triangulated(0), number_of_texture_coordinate_indexes(0), 
+  is_rgba(false), behaviour(PRC_GRAPHICS_Show)
+  {}
+  void serializeTessFace(PRCbitStream&);
+  std::vector<uint32_t> line_attributes;
+  uint32_t start_wire;                 // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+  std::vector<uint32_t> sizes_wire;    // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+  uint32_t used_entities_flag;
+  uint32_t start_triangulated;
+  std::vector<uint32_t> sizes_triangulated;
+  uint32_t number_of_texture_coordinate_indexes;
+  bool is_rgba;
+  std::vector<uint8_t> rgba_vertices;
+  uint32_t behaviour;
+};
+typedef std::deque <PRCTessFace*>  PRCTessFaceList;
+
+class PRCContentBaseTessData
+{
+public:
+  PRCContentBaseTessData() :
+  is_calculated(false) {}
+  void serializeContentBaseTessData(PRCbitStream&);
+  bool is_calculated;
+  std::vector<double> coordinates;
+};
+
+class PRCTess : public PRCContentBaseTessData
+{
+public:
+  virtual ~PRCTess() {}
+  virtual void serializeBaseTessData(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCTess*>  PRCTessList;
+
+class PRC3DTess : public PRCTess
+{
+public:
+  PRC3DTess() :
+  has_faces(false), has_loops(false),
+  crease_angle(80)
+  {}
+  ~PRC3DTess() { for(PRCTessFaceList::iterator it=face_tessellation.begin(); it!=face_tessellation.end(); ++it) delete *it; }
+  void serialize3DTess(PRCbitStream&);
+  void serializeBaseTessData(PRCbitStream &pbs) { serialize3DTess(pbs); }
+  void addTessFace(PRCTessFace*& pTessFace);
+
+  bool has_faces;
+  bool has_loops;
+  double crease_angle;
+  std::vector<double> normal_coordinate;
+  std::vector<uint32_t> wire_index;            // specifing bounding wire seems not to work as of Acrobat/Reader 9.2
+  std::vector<uint32_t> triangulated_index;
+  PRCTessFaceList face_tessellation;
+  std::vector<double> texture_coordinate;
+};
+
+class PRC3DWireTess : public PRCTess
+{
+public:
+  PRC3DWireTess() :
+  is_rgba(false), is_segment_color(false) {}
+  void serialize3DWireTess(PRCbitStream&);
+  void serializeBaseTessData(PRCbitStream &pbs) { serialize3DWireTess(pbs); }
+
+  bool is_rgba;
+  bool is_segment_color;
+  std::vector<uint32_t> wire_indexes;
+  std::vector<uint8_t> rgba_vertices;
+};
+
+class PRCMarkupTess : public PRCTess
+{
+public:
+  PRCMarkupTess() :
+  behaviour(0)
+  {}
+  void serializeMarkupTess(PRCbitStream&);
+  void serializeBaseTessData(PRCbitStream &pbs) { serializeMarkupTess(pbs); }
+
+  std::vector<uint32_t> codes;
+  std::vector<std::string> texts;
+  std::string label;
+  uint8_t behaviour;
+};
+
+class PRCGraphics
+{
+public:
+  PRCGraphics() : layer_index(m1), index_of_line_style(m1), behaviour_bit_field(PRC_GRAPHICS_Show) {}
+  void serializeGraphics(PRCbitStream&);
+  void serializeGraphicsForced(PRCbitStream&);
+  bool has_graphics() { return (index_of_line_style!=m1 || layer_index!=m1 || behaviour_bit_field!=PRC_GRAPHICS_Show) ; }
+  uint32_t layer_index;
+  uint32_t index_of_line_style;
+  uint16_t behaviour_bit_field;
+};
+typedef std::deque <PRCGraphics*>  PRCGraphicsList;
+
+void writeGraphics(PRCbitStream&,const PRCGraphics&,bool=false);
+
+class PRCMarkup: public PRCGraphics, public ContentPRCBase
+{
+public:
+  PRCMarkup(std::string n="") :
+    ContentPRCBase(PRC_TYPE_MKP_Markup,n),
+    type(KEPRCMarkupType_Unknown), sub_type(KEPRCMarkupSubType_Unknown), index_tessellation(m1) {}
+  void serializeMarkup(PRCbitStream&);
+  EPRCMarkupType type;
+  EPRCMarkupSubType sub_type;
+// vector<PRCReferenceUniqueIdentifier> linked_items;
+// vector<PRCReferenceUniqueIdentifier> leaders;
+  uint32_t index_tessellation;
+};
+typedef std::deque <PRCMarkup*>  PRCMarkupList;
+
+class PRCAnnotationItem: public PRCGraphics, public ContentPRCBase
+{
+public:
+  PRCAnnotationItem(std::string n="") :
+    ContentPRCBase(PRC_TYPE_MKP_AnnotationItem,n) {}
+  void serializeAnnotationItem(PRCbitStream&);
+  void serializeAnnotationEntity(PRCbitStream &pbs) { serializeAnnotationItem(pbs); }
+  PRCReferenceUniqueIdentifier markup;
+};
+typedef std::deque <PRCAnnotationItem*>  PRCAnnotationItemList;
+
+class PRCRepresentationItemContent: public PRCGraphics, public ContentPRCBase
+{
+public:
+  PRCRepresentationItemContent(uint32_t t, std::string n="") :
+    ContentPRCBase(t,n),
+    index_local_coordinate_system(m1), index_tessellation(m1) {}
+  void serializeRepresentationItemContent(PRCbitStream&);
+  uint32_t index_local_coordinate_system;
+  uint32_t index_tessellation;
+};
+
+class PRCRepresentationItem : public PRCRepresentationItemContent
+{
+public:
+  PRCRepresentationItem(uint32_t t, std::string n="") :
+    PRCRepresentationItemContent(t,n) {}
+  virtual ~PRCRepresentationItem() {}
+  virtual void serializeRepresentationItem(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCRepresentationItem*>  PRCRepresentationItemList;
+
+class PRCBrepModel : public PRCRepresentationItem
+{
+public:
+  PRCBrepModel(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_BrepModel,n), has_brep_data(true), context_id(m1), body_id(m1), is_closed(false) {}
+  void serializeBrepModel(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializeBrepModel(pbs); }
+  bool has_brep_data;
+  uint32_t context_id;
+  uint32_t body_id;
+  bool is_closed;
+};
+
+class PRCPolyBrepModel : public PRCRepresentationItem
+{
+public:
+  PRCPolyBrepModel(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_PolyBrepModel,n), is_closed(false) {}
+  void serializePolyBrepModel(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyBrepModel(pbs); }
+  bool is_closed;
+};
+
+class PRCPointSet : public PRCRepresentationItem
+{
+public:
+  PRCPointSet(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_PointSet,n) {}
+  void serializePointSet(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializePointSet(pbs); }
+  std::vector<PRCVector3d> point;
+};
+
+class PRCWire : public PRCRepresentationItem
+{
+public:
+  PRCWire(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_Curve,n), has_wire_body(true), context_id(m1), body_id(m1) {}
+  void serializeWire(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializeWire(pbs); }
+  bool has_wire_body;
+  uint32_t context_id;
+  uint32_t body_id;
+};
+
+class PRCPolyWire : public PRCRepresentationItem
+{
+public:
+  PRCPolyWire(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_PolyWire,n) {}
+  void serializePolyWire(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializePolyWire(pbs); }
+};
+
+class PRCSet : public PRCRepresentationItem
+{
+public:
+  PRCSet(std::string n="") :
+    PRCRepresentationItem(PRC_TYPE_RI_Set,n) {}
+  ~PRCSet() { for(PRCRepresentationItemList::iterator it=elements.begin(); it!=elements.end(); ++it) delete *it; }
+  void serializeSet(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializeSet(pbs); }
+  uint32_t addBrepModel(PRCBrepModel*& pBrepModel);
+  uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel);
+  uint32_t addPointSet(PRCPointSet*& pPointSet);
+  uint32_t addSet(PRCSet*& pSet);
+  uint32_t addWire(PRCWire*& pWire);
+  uint32_t addPolyWire(PRCPolyWire*& pPolyWire);
+  uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem);
+  PRCRepresentationItemList elements;
+};
+
+class PRCTransformation3d
+{
+public:
+  virtual ~PRCTransformation3d() {}
+  virtual void serializeTransformation3d(PRCbitStream&) const =0;
+};
+typedef std::deque <PRCTransformation3d*> PRCTransformation3dList;
+
+class PRCGeneralTransformation3d : public PRCTransformation3d
+{
+public:
+  PRCGeneralTransformation3d()
+  {
+    setidentity();
+  }
+  PRCGeneralTransformation3d(const double t[])
+  {
+    set(t);
+  }
+  
+  void serializeGeneralTransformation3d(PRCbitStream&) const;
+  void serializeTransformation3d(PRCbitStream& pbs)  const { serializeGeneralTransformation3d(pbs); }
+  double m_coef[16];
+  bool operator==(const PRCGeneralTransformation3d &t) const
+  {
+    for (size_t i=0;i<16;i++)
+        if(m_coef[i]!=t.m_coef[i])
+         return false;
+    return true;
+  }
+  bool operator<(const PRCGeneralTransformation3d &t) const
+  {
+    for (size_t i=0;i<16;i++)
+        if(m_coef[i]!=t.m_coef[i])
+        {
+          return (m_coef[i]<t.m_coef[i]);
+        }
+    return false;
+  }
+  void set(const double t[])
+  {
+    if(t!=NULL) 
+      for (size_t i=0;i<16;i++)
+          m_coef[i]=t[i];
+    else
+      setidentity();
+  }
+  void setidentity()
+  {
+    m_coef[0]=1; m_coef[4]=0; m_coef[ 8]=0; m_coef[12]=0;
+    m_coef[1]=0; m_coef[5]=1; m_coef[ 9]=0; m_coef[13]=0;
+    m_coef[2]=0; m_coef[6]=0; m_coef[10]=1; m_coef[14]=0;
+    m_coef[3]=0; m_coef[7]=0; m_coef[11]=0; m_coef[15]=1;
+  }
+  bool isnotidtransform() const {
+    return(
+           m_coef[0]!=1 || m_coef[4]!=0 || m_coef[ 8]!=0 || m_coef[12]!=0 ||
+           m_coef[1]!=0 || m_coef[5]!=1 || m_coef[ 9]!=0 || m_coef[13]!=0 ||
+           m_coef[2]!=0 || m_coef[6]!=0 || m_coef[10]!=1 || m_coef[14]!=0 ||
+           m_coef[3]!=0 || m_coef[7]!=0 || m_coef[11]!=0 || m_coef[15]!=1 );
+  }
+  bool isidtransform() const {
+    return(
+           m_coef[0]==1 && m_coef[4]==0 && m_coef[ 8]==0 && m_coef[12]==0 &&
+           m_coef[1]==0 && m_coef[5]==1 && m_coef[ 9]==0 && m_coef[13]==0 &&
+           m_coef[2]==0 && m_coef[6]==0 && m_coef[10]==1 && m_coef[14]==0 &&
+           m_coef[3]==0 && m_coef[7]==0 && m_coef[11]==0 && m_coef[15]==1 );
+  }
+  double M(size_t i, size_t j) const {
+    return m_coef[i+j*4];
+  }
+};
+typedef std::deque <PRCGeneralTransformation3d> PRCGeneralTransformation3dList;
+
+class PRCCartesianTransformation3d : public PRCTransformation3d
+{
+public:
+  PRCCartesianTransformation3d() :
+    behaviour(PRC_TRANSFORMATION_Identity), origin(0.0,0.0,0.0), X(1.0,0.0,0.0), Y(0.0,1.0,0.0), Z(0.0,0.0,1.0),
+    scale(1.0,1.0,1.0), uniform_scale(1.0),
+    X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0) {}
+  PRCCartesianTransformation3d(const double o[3], const double x[3], const double y[3], double sc) :
+    behaviour(PRC_TRANSFORMATION_Identity), origin(o,0.0,0.0,0.0), X(x,1.0,0.0,0.0), Y(y,0.0,1.0,0.0), Z(0.0,0.0,1.0),
+    scale(1.0,1.0,1.0), uniform_scale(sc),
+    X_homogeneous_coord(0.0), Y_homogeneous_coord(0.0), Z_homogeneous_coord(0.0), origin_homogeneous_coord(1.0)
+    {
+      if(origin!=PRCVector3d(0.0,0.0,0.0))
+        behaviour = behaviour | PRC_TRANSFORMATION_Translate;
+      if(X!=PRCVector3d(1.0,0.0,0.0) || Y!=PRCVector3d(0.0,1.0,0.0))
+        behaviour = behaviour | PRC_TRANSFORMATION_Rotate;
+      if(uniform_scale!=1)
+        behaviour = behaviour | PRC_TRANSFORMATION_Scale;
+    }
+  void serializeCartesianTransformation3d(PRCbitStream& pbs) const;
+  void serializeTransformation3d(PRCbitStream& pbs) const { serializeCartesianTransformation3d(pbs); }
+  uint8_t behaviour;
+  PRCVector3d origin;
+  PRCVector3d X;
+  PRCVector3d Y;
+  PRCVector3d Z;
+  PRCVector3d scale;
+  double uniform_scale;
+  double X_homogeneous_coord;
+  double Y_homogeneous_coord;
+  double Z_homogeneous_coord;
+  double origin_homogeneous_coord;
+  bool operator==(const PRCCartesianTransformation3d &t) const
+  {
+    return behaviour==t.behaviour && origin==t.origin && X==t.X && Y==t.Y && Z==t.Z && scale==t.scale && uniform_scale==t.uniform_scale &&
+           X_homogeneous_coord==t.X_homogeneous_coord && Y_homogeneous_coord==t.Y_homogeneous_coord &&
+           Z_homogeneous_coord==t.Z_homogeneous_coord && origin_homogeneous_coord==t.origin_homogeneous_coord;
+  }
+};
+
+class PRCTransformation
+{
+public:
+  PRCTransformation() :
+    has_transformation(false), geometry_is_2D(false), behaviour(PRC_TRANSFORMATION_Identity),
+    origin(0.0,0.0,0.0), x_axis(1.0,0.0,0.0), y_axis(0.0,1.0,0.0), scale(1) {}
+  void serializeTransformation(PRCbitStream&);
+  bool has_transformation;
+  bool geometry_is_2D;
+  uint8_t behaviour;
+  PRCVector3d origin;
+  PRCVector3d x_axis;
+  PRCVector3d y_axis;
+  double scale;
+};
+
+class PRCCoordinateSystem : public PRCRepresentationItem
+{
+public:
+  PRCCoordinateSystem(std::string n="") :
+  PRCRepresentationItem(PRC_TYPE_RI_CoordinateSystem,n), axis_set(NULL) {}
+  ~PRCCoordinateSystem() { delete axis_set; }
+  void serializeCoordinateSystem(PRCbitStream&);
+  void serializeRepresentationItem(PRCbitStream &pbs) { serializeCoordinateSystem(pbs); }
+  void setAxisSet(PRCGeneralTransformation3d*& transform) { axis_set = transform; transform = NULL; } 
+  void setAxisSet(PRCCartesianTransformation3d*& transform) { axis_set = transform; transform = NULL; } 
+  PRCTransformation3d *axis_set;
+  bool operator==(const PRCCoordinateSystem &t) const
+  {
+    if(index_local_coordinate_system!=t.index_local_coordinate_system)
+      return false;
+    PRCGeneralTransformation3d*       axis_set_general = dynamic_cast<PRCGeneralTransformation3d*>(axis_set);
+    PRCGeneralTransformation3d*     t_axis_set_general = dynamic_cast<PRCGeneralTransformation3d*>(t.axis_set);
+    PRCCartesianTransformation3d*   axis_set_cartesian = dynamic_cast<PRCCartesianTransformation3d*>(axis_set);
+    PRCCartesianTransformation3d* t_axis_set_cartesian = dynamic_cast<PRCCartesianTransformation3d*>(t.axis_set);
+    if(axis_set_general!=NULL)
+      return (t_axis_set_general!=NULL?(*axis_set_general==*t_axis_set_general):false); 
+    if(axis_set_cartesian!=NULL)
+      return (t_axis_set_cartesian!=NULL?(*axis_set_cartesian==*t_axis_set_cartesian):false); 
+    return false;
+  }
+};
+typedef std::deque <PRCCoordinateSystem*>  PRCCoordinateSystemList;
+
+struct PRCFontKey
+{
+  uint32_t font_size;
+  uint8_t  attributes;
+};
+
+class PRCFontKeysSameFont
+{
+public:
+  void serializeFontKeysSameFont(PRCbitStream&);
+  std::string font_name;
+  uint32_t char_set;
+  std::vector<PRCFontKey> font_keys;
+
+};
+
+// Topology
+class PRCBaseGeometry : public PRCAttributes
+{
+public:
+  PRCBaseGeometry() :
+    base_information(false), identifier(0) {}
+  PRCBaseGeometry(std::string n, uint32_t id = 0) :
+    base_information(true),name(n),identifier(id) {}
+  void serializeBaseGeometry(PRCbitStream&);
+  bool base_information;
+  std::string name;
+  uint32_t identifier;
+};
+
+class PRCBoundingBox
+{
+public:
+  PRCBoundingBox() : min(0.0,0.0,0.0), max(0.0,0.0,0.0) {}
+  PRCBoundingBox(const PRCVector3d &m1, const PRCVector3d& m2) : min(m1),max(m2) {}
+  void serializeBoundingBox(PRCbitStream &pbs);
+  PRCVector3d min;
+  PRCVector3d max;
+};
+
+class PRCDomain
+{
+public:
+  void serializeDomain(PRCbitStream &pbs);
+  PRCVector2d min;
+  PRCVector2d max;
+};
+
+class PRCInterval
+{
+public:
+  PRCInterval() : min(0), max(0) {}
+  PRCInterval(double m, double M) : min(m), max(M) {}
+  void serializeInterval(PRCbitStream &pbs);
+  double min;
+  double max;
+};
+
+class PRCParameterization
+{
+public:
+  PRCParameterization() : parameterization_coeff_a(1), parameterization_coeff_b(0) {}
+  PRCParameterization(double min, double max) : interval(min, max), parameterization_coeff_a(1), parameterization_coeff_b(0) {}
+  void serializeParameterization(PRCbitStream &pbs);
+  PRCInterval interval;
+  double parameterization_coeff_a;
+  double parameterization_coeff_b;
+};
+
+class PRCUVParameterization
+{
+public:
+  PRCUVParameterization() : swap_uv(false),
+    parameterization_on_u_coeff_a(1), parameterization_on_v_coeff_a(1),
+    parameterization_on_u_coeff_b(0), parameterization_on_v_coeff_b(0) {}
+  void serializeUVParameterization(PRCbitStream &pbs);
+  bool swap_uv;
+  PRCDomain uv_domain;
+  double parameterization_on_u_coeff_a;
+  double parameterization_on_v_coeff_a;
+  double parameterization_on_u_coeff_b;
+  double parameterization_on_v_coeff_b;
+};
+
+class PRCControlPoint
+{
+public:
+  PRCControlPoint() :
+   x(0), y(0), z(0), w(1) {}
+  PRCControlPoint(double X, double Y, double Z=0, double W=1) :
+   x(X), y(Y), z(Z), w(W) {}
+  PRCControlPoint(const PRCVector3d &v) :
+   x(v.x), y(v.y), z(v.z), w(1) {}
+  void Set(double fx, double fy, double fz, double fw=1)
+   { x = fx; y = fy; z = fz; w = fw; }
+  double x;
+  double y;
+  double z;
+  double w;
+};
+
+class PRCContentSurface: public PRCBaseGeometry
+{
+public:
+  PRCContentSurface() :
+    PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone) {}
+  PRCContentSurface(std::string n) :
+    PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone) {} 
+  void serializeContentSurface(PRCbitStream&);
+  EPRCExtendType extend_info;
+};
+
+class PRCSurface : public PRCContentSurface
+{
+public:
+  PRCSurface() :
+    PRCContentSurface() {}
+  PRCSurface(std::string n) :
+    PRCContentSurface(n) {}
+  virtual ~PRCSurface() {}
+  virtual void  serializeSurface(PRCbitStream &pbs) = 0;
+};
+
+class PRCNURBSSurface : public PRCSurface
+{
+public:
+  PRCNURBSSurface() :
+    PRCSurface(), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {}
+  PRCNURBSSurface(std::string n) :
+    PRCSurface(n), knot_type(KEPRCKnotTypeUnspecified), surface_form(KEPRCBSplineSurfaceFormUnspecified) {}
+  void  serializeNURBSSurface(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeNURBSSurface(pbs); }
+  bool is_rational;
+  uint32_t degree_in_u;
+  uint32_t degree_in_v;
+  std::vector<PRCControlPoint> control_point;
+  std::vector<double> knot_u;
+  std::vector<double> knot_v;
+  const EPRCKnotType knot_type;
+  const EPRCBSplineSurfaceForm surface_form;
+};
+
+class PRCContentCurve: public PRCBaseGeometry
+{
+public:
+  PRCContentCurve() :
+    PRCBaseGeometry(), extend_info(KEPRCExtendTypeNone), is_3d(true) {}
+  PRCContentCurve(std::string n) :
+    PRCBaseGeometry(n,makeCADID()),extend_info(KEPRCExtendTypeNone), is_3d(true) {} 
+  void serializeContentCurve(PRCbitStream&);
+  EPRCExtendType extend_info;
+  bool is_3d;
+};
+
+class PRCCurve : public PRCContentCurve
+{
+public:
+  PRCCurve() :
+    PRCContentCurve() {}
+  PRCCurve(std::string n) :
+    PRCContentCurve(n) {}
+  virtual ~PRCCurve() {}
+  virtual void  serializeCurve(PRCbitStream &pbs) = 0;
+};
+typedef std::deque <PRCCurve*>  PRCCurveList;
+
+class PRCNURBSCurve : public PRCCurve
+{
+public:
+  PRCNURBSCurve() :
+    PRCCurve(), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {}
+  PRCNURBSCurve(std::string n) :
+    PRCCurve(n), knot_type(KEPRCKnotTypeUnspecified), curve_form(KEPRCBSplineCurveFormUnspecified) {}
+  void  serializeNURBSCurve(PRCbitStream &pbs);
+  void  serializeCurve(PRCbitStream &pbs) { serializeNURBSCurve(pbs); }
+  bool is_rational;
+  uint32_t degree;
+  std::vector<PRCControlPoint> control_point;
+  std::vector<double> knot;
+  const EPRCKnotType knot_type;
+  const EPRCBSplineCurveForm curve_form;
+};
+
+class PRCPolyLine : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+  PRCPolyLine() :
+    PRCCurve() {}
+  PRCPolyLine(std::string n) :
+    PRCCurve(n) {}
+  void  serializePolyLine(PRCbitStream &pbs);
+  void  serializeCurve(PRCbitStream &pbs) { serializePolyLine(pbs); }
+  std::vector<PRCVector3d> point;
+};
+
+class PRCCircle : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+  PRCCircle() :
+    PRCCurve(), PRCParameterization(0,2*pi) {}
+  PRCCircle(std::string n) :
+    PRCCurve(n), PRCParameterization(0,2*pi) {}
+  void  serializeCircle(PRCbitStream &pbs);
+  void  serializeCurve(PRCbitStream &pbs) { serializeCircle(pbs); }
+  double radius;
+};
+
+class PRCComposite : public PRCCurve, public PRCTransformation, public PRCParameterization
+{
+public:
+  PRCComposite() :
+    PRCCurve() {}
+  PRCComposite(std::string n) :
+    PRCCurve(n) {}
+  void  serializeComposite(PRCbitStream &pbs);
+  void  serializeCurve(PRCbitStream &pbs) { serializeComposite(pbs); }
+  PRCCurveList base_curve;
+  std::vector<bool> base_sense;
+  bool is_closed;
+};
+
+class PRCBlend01 : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCBlend01() :
+    PRCSurface(), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {}
+  PRCBlend01(std::string n) :
+    PRCSurface(n), center_curve(NULL), origin_curve(NULL), tangent_curve(NULL) {}
+  ~PRCBlend01() { delete center_curve; delete origin_curve; delete tangent_curve; }
+  void  serializeBlend01(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeBlend01(pbs); }
+// void  setCenterCurve (PRCCurve*& curve) { center_curve  = curve; curve = NULL; }
+// void  setOriginCurve (PRCCurve*& curve) { origin_curve  = curve; curve = NULL; }
+// void  setTangentCurve(PRCCurve*& curve) { tangent_curve = curve; curve = NULL; }
+  PRCCurve* center_curve;
+  PRCCurve* origin_curve;
+  PRCCurve* tangent_curve;
+};
+
+class PRCRuled : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCRuled() :
+    PRCSurface(), first_curve(NULL), second_curve(NULL) {}
+  PRCRuled(std::string n) :
+    PRCSurface(n) {}
+  ~PRCRuled() { delete first_curve; delete second_curve; }
+  void  serializeRuled(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeRuled(pbs); }
+// void  setFirstCurve(PRCCurve*&  curve) { first_curve  = curve; curve = NULL; }
+// void  setSecondCurve(PRCCurve*& curve) { second_curve = curve; curve = NULL; }
+  PRCCurve* first_curve;
+  PRCCurve* second_curve;
+};
+
+class PRCSphere : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCSphere() :
+    PRCSurface() {}
+  PRCSphere(std::string n) :
+    PRCSurface(n) {}
+  void  serializeSphere(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeSphere(pbs); }
+  double radius;
+};
+
+class PRCCone : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCCone() :
+    PRCSurface() {}
+  PRCCone(std::string n) :
+    PRCSurface(n) {}
+  void  serializeCone(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeCone(pbs); }
+  double bottom_radius;
+  double semi_angle;
+};
+
+class PRCCylinder : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCCylinder() :
+    PRCSurface() {}
+  PRCCylinder(std::string n) :
+    PRCSurface(n) {}
+  void  serializeCylinder(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeCylinder(pbs); }
+  double radius;
+};
+
+class PRCTorus : public PRCSurface, public PRCTransformation, public PRCUVParameterization
+{
+public:
+  PRCTorus() :
+    PRCSurface() {}
+  PRCTorus(std::string n) :
+    PRCSurface(n) {}
+  void  serializeTorus(PRCbitStream &pbs);
+  void  serializeSurface(PRCbitStream &pbs) { serializeTorus(pbs); }
+  double major_radius;
+  double minor_radius;
+};
+
+class PRCBaseTopology : public PRCAttributes
+{
+public:
+  PRCBaseTopology() :
+    base_information(false),identifier(0) {}
+  PRCBaseTopology(std::string n, uint32_t id = 0) :
+    base_information(true),name(n),identifier(id) {}
+  void serializeBaseTopology(PRCbitStream&);
+  bool base_information;
+  std::string name;
+  uint32_t identifier;
+};
+
+class PRCTopoItem
+{
+public:
+  virtual ~PRCTopoItem() {}
+  virtual void serializeTopoItem(PRCbitStream&)=0;
+};
+
+class PRCContentBody: public PRCBaseTopology
+{
+public:
+  PRCContentBody() :
+    PRCBaseTopology(), behavior(0) {}
+  PRCContentBody(std::string n) :
+    PRCBaseTopology(n,makeCADID()), behavior(0) {}
+  void serializeContentBody(PRCbitStream&);
+  uint8_t behavior;
+};
+
+class PRCBody : public PRCContentBody, public PRCTopoItem
+{
+public:
+  PRCBody() :
+    PRCContentBody(), topo_item_type(PRC_TYPE_ROOT) {}
+  PRCBody(uint32_t tit) :
+    PRCContentBody(), topo_item_type(tit) {}
+  PRCBody(uint32_t tit, std::string n) :
+    PRCContentBody(n), topo_item_type(tit) {}
+  virtual ~PRCBody() {}
+  virtual void serializeBody(PRCbitStream &pbs) = 0;
+  void serializeTopoItem(PRCbitStream &pbs) { serializeBody(pbs); }
+  uint32_t serialType() { return topo_item_type; }
+  virtual double serialTolerance() { return 0; }
+  const uint32_t topo_item_type;
+};
+typedef std::deque <PRCBody*>  PRCBodyList;
+
+class PRCContentWireEdge : public PRCBaseTopology
+{
+public:
+  PRCContentWireEdge() :
+    PRCBaseTopology(), curve_3d(NULL), has_curve_trim_interval(false) {}
+  PRCContentWireEdge(std::string n) :
+    PRCBaseTopology(n,makeCADID()), curve_3d(NULL), has_curve_trim_interval(false) {} 
+  ~PRCContentWireEdge() { delete curve_3d; }
+  void serializeContentWireEdge(PRCbitStream &pbs);
+// void setCurve(PRCCurve*& curve) { curve_3d = curve; curve = NULL; }
+  PRCCurve* curve_3d;
+  bool has_curve_trim_interval;
+  PRCInterval curve_trim_interval;
+};
+
+class PRCWireEdge : public PRCContentWireEdge, public PRCTopoItem
+{
+public:
+  void serializeWireEdge(PRCbitStream &pbs);
+  void serializeTopoItem(PRCbitStream &pbs) { serializeWireEdge(pbs); }
+};
+
+class PRCSingleWireBody : public PRCBody
+{
+public:
+  PRCSingleWireBody() :
+    PRCBody(PRC_TYPE_TOPO_SingleWireBody), wire_edge(NULL) {}
+  PRCSingleWireBody(std::string n) :
+    PRCBody(PRC_TYPE_TOPO_SingleWireBody, n), wire_edge(NULL) {}
+  ~PRCSingleWireBody() { delete wire_edge; }
+  void serializeSingleWireBody(PRCbitStream &pbs);
+  void serializeBody(PRCbitStream &pbs) { serializeSingleWireBody(pbs); }
+  void setWireEdge(PRCWireEdge*& wireEdge) { wire_edge = wireEdge; wireEdge = NULL; }  
+  PRCWireEdge* wire_edge;
+};
+
+class PRCFace : public PRCBaseTopology, public PRCTopoItem, public PRCGraphics
+{
+public:
+  PRCFace() :
+    PRCBaseTopology(), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {}
+  PRCFace(std::string n) :
+    PRCBaseTopology(n,makeCADID()), base_surface(NULL), have_surface_trim_domain(false), have_tolerance(false), tolerance(0), number_of_loop(0), outer_loop_index(-1) {} 
+  ~PRCFace() { delete base_surface; }
+  void serializeFace(PRCbitStream &pbs);
+  void serializeTopoItem(PRCbitStream &pbs) { serializeFace(pbs); }
+  void setBaseSurface(PRCSurface*& surface) { base_surface = surface; surface = NULL; }
+  PRCSurface *base_surface;
+  const bool have_surface_trim_domain;
+  PRCDomain surface_trim_domain;
+  const bool have_tolerance;
+  const double tolerance;
+  const uint32_t number_of_loop;
+  const int32_t outer_loop_index;
+// PRCLoopList loop;
+};
+typedef std::deque <PRCFace*>  PRCFaceList;
+
+class PRCShell : public PRCBaseTopology, public PRCTopoItem
+{
+public:
+  PRCShell() :
+    PRCBaseTopology(), shell_is_closed(false) {}
+  PRCShell(std::string n) :
+    PRCBaseTopology(n,makeCADID()), shell_is_closed(false) {}
+  ~PRCShell() { for(PRCFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; }
+  void serializeShell(PRCbitStream &pbs);
+  void serializeTopoItem(PRCbitStream &pbs) { serializeShell(pbs); }
+  void addFace(PRCFace*& pFace, uint8_t orientation=2);
+  bool shell_is_closed;
+  PRCFaceList face;
+  std::vector<uint8_t> orientation_surface_with_shell;
+};
+typedef std::deque <PRCShell*>  PRCShellList;
+
+class PRCConnex : public PRCBaseTopology, public PRCTopoItem
+{
+public:
+  PRCConnex() :
+    PRCBaseTopology() {}
+  PRCConnex(std::string n) :
+    PRCBaseTopology(n,makeCADID()) {} 
+  ~PRCConnex() { for(PRCShellList::iterator it=shell.begin(); it!=shell.end(); ++it) delete *it; }
+  void serializeConnex(PRCbitStream &pbs);
+  void serializeTopoItem(PRCbitStream &pbs) { serializeConnex(pbs); }
+  void addShell(PRCShell*& pShell);
+  PRCShellList shell;
+};
+typedef std::deque <PRCConnex*>  PRCConnexList;
+
+class PRCBrepData : public PRCBody, public PRCBoundingBox
+{
+public:
+  PRCBrepData() :
+    PRCBody(PRC_TYPE_TOPO_BrepData) {}
+  PRCBrepData(std::string n) :
+    PRCBody(PRC_TYPE_TOPO_BrepData, n) {}
+  ~PRCBrepData() { for(PRCConnexList::iterator it=connex.begin(); it!=connex.end(); ++it) delete *it; }
+  void serializeBrepData(PRCbitStream &pbs);
+  void serializeBody(PRCbitStream &pbs) { serializeBrepData(pbs); }
+  void addConnex(PRCConnex*& pConnex);
+  PRCConnexList connex;
+};
+
+// For now - treat just the case of Bezier surfaces cubic 4x4 or linear 2x2
+class PRCCompressedFace : public PRCBaseTopology, public PRCGraphics
+{
+public:
+  PRCCompressedFace() :
+    PRCBaseTopology(), orientation_surface_with_shell(true), degree(0) {}
+  PRCCompressedFace(std::string n) :
+    PRCBaseTopology(n,makeCADID()), orientation_surface_with_shell(true), degree(0) {} 
+  void serializeCompressedFace(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+  void serializeContentCompressedFace(PRCbitStream &pbs);
+  void serializeCompressedAnaNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+  void serializeCompressedNurbs(PRCbitStream &pbs, double brep_data_compressed_tolerance);
+  bool orientation_surface_with_shell;
+  uint32_t degree;
+  std::vector<PRCVector3d> control_point;
+};
+typedef std::deque <PRCCompressedFace*>  PRCCompressedFaceList;
+
+// For now - treat just the case of one connex/one shell
+class PRCCompressedBrepData : public PRCBody
+{
+public:
+  PRCCompressedBrepData() :
+    PRCBody(PRC_TYPE_TOPO_BrepDataCompress), serial_tolerance(0), brep_data_compressed_tolerance(0) {}
+  PRCCompressedBrepData(std::string n) :
+    PRCBody(PRC_TYPE_TOPO_BrepDataCompress, n), serial_tolerance(0), brep_data_compressed_tolerance(0) {}
+  ~PRCCompressedBrepData() { for(PRCCompressedFaceList::iterator it=face.begin(); it!=face.end(); ++it) delete *it; }
+  void serializeCompressedBrepData(PRCbitStream &pbs);
+  void serializeBody(PRCbitStream &pbs) { serializeCompressedBrepData(pbs); }
+  void serializeCompressedShell(PRCbitStream &pbs);
+  double serialTolerance() { return serial_tolerance; }
+  double serial_tolerance;
+  double brep_data_compressed_tolerance;
+  PRCCompressedFaceList face;
+};
+
+class PRCTopoContext : public ContentPRCBase
+{
+public:
+  PRCTopoContext(std::string n="") :
+  ContentPRCBase(PRC_TYPE_TOPO_Context,n), behaviour(0), granularity(1), tolerance(0),
+   have_smallest_face_thickness(false), smallest_thickness(0), have_scale(false), scale(1) {}
+  ~PRCTopoContext() { for(PRCBodyList::iterator it=body.begin(); it!=body.end(); ++it) delete *it; }
+  void serializeTopoContext(PRCbitStream&);
+  void serializeContextAndBodies(PRCbitStream&);
+  void serializeGeometrySummary(PRCbitStream&);
+  void serializeContextGraphics(PRCbitStream&);
+  uint32_t addSingleWireBody(PRCSingleWireBody*& body);
+  uint32_t addBrepData(PRCBrepData*& body);
+  uint32_t addCompressedBrepData(PRCCompressedBrepData*& body);
+  uint8_t  behaviour;
+  double granularity;
+  double tolerance;
+  bool have_smallest_face_thickness;
+  double smallest_thickness;
+  bool have_scale;
+  double scale;
+  PRCBodyList body;
+};
+typedef std::deque <PRCTopoContext*>  PRCTopoContextList;
+
+class PRCUniqueId
+{
+public:
+  PRCUniqueId() : id0(0), id1(0), id2(0), id3(0)  {}
+  void serializeCompressedUniqueId(PRCbitStream&) const;
+  void serializeFileStructureUncompressedUniqueId(std::ostream& out) const;
+  uint32_t id0;
+  uint32_t id1;
+  uint32_t id2;
+  uint32_t id3;
+};
+
+class PRCUnit
+{
+public:
+  PRCUnit() : unit_from_CAD_file(false), unit(1) {}
+  PRCUnit(double u, bool ufcf=true) : unit_from_CAD_file(ufcf), unit(u) {}
+  void serializeUnit(PRCbitStream&);
+  bool unit_from_CAD_file;
+  double unit;
+};
+
+class PRCProductOccurrence: public PRCGraphics, public ContentPRCBase
+{
+public:
+  PRCProductOccurrence(std::string n="") :
+    ContentPRCBase(PRC_TYPE_ASM_ProductOccurence,n),
+    index_part(m1),
+    index_prototype(m1), prototype_in_same_file_structure(true),
+    index_external_data(m1), external_data_in_same_file_structure(true),
+    product_behaviour(0), product_information_flags(0), product_load_status(KEPRCProductLoadStatus_Loaded),
+    location(NULL) {}
+  ~PRCProductOccurrence() { delete location; }
+  void setLocation(PRCGeneralTransformation3d*& transform) { location = transform; transform = NULL; }
+  void serializeProductOccurrence(PRCbitStream&);
+  uint32_t index_part;
+  uint32_t index_prototype;
+  bool prototype_in_same_file_structure;
+  PRCUniqueId prototype_file_structure;
+  uint32_t index_external_data;
+  bool external_data_in_same_file_structure;
+  PRCUniqueId external_data_file_structure;
+  std::vector<uint32_t> index_son_occurrence;
+  uint8_t product_behaviour;
+  PRCUnit unit_information;
+  uint8_t product_information_flags;
+  EPRCProductLoadStatus product_load_status;
+  PRCGeneralTransformation3d *location;
+};
+typedef std::deque <PRCProductOccurrence*>  PRCProductOccurrenceList;
+
+class PRCPartDefinition: public PRCGraphics, public ContentPRCBase, public PRCBoundingBox
+{
+public:
+       PRCPartDefinition(std::string n="") :
+    ContentPRCBase(PRC_TYPE_ASM_PartDefinition,n) {}
+  ~PRCPartDefinition() { for(PRCRepresentationItemList::iterator it=representation_item.begin(); it!=representation_item.end(); ++it) delete *it; }
+       void serializePartDefinition(PRCbitStream&);
+       uint32_t addBrepModel(PRCBrepModel*& pBrepModel);
+       uint32_t addPolyBrepModel(PRCPolyBrepModel*& pPolyBrepModel);
+       uint32_t addPointSet(PRCPointSet*& pPointSet);
+       uint32_t addSet(PRCSet*& pSet);
+       uint32_t addWire(PRCWire*& pWire);
+       uint32_t addPolyWire(PRCPolyWire*& pPolyWire);
+       uint32_t addRepresentationItem(PRCRepresentationItem*& pRepresentationItem);
+       PRCRepresentationItemList representation_item;
+};
+typedef std::deque <PRCPartDefinition*>  PRCPartDefinitionList;
+
+#endif //__WRITE_PRC_H
diff --git a/src/s_hull/COPYING.txt b/src/s_hull/COPYING.txt
new file mode 100644 (file)
index 0000000..77b475d
--- /dev/null
@@ -0,0 +1,43 @@
+S-hull, Copyright (c) 2010
+Dr David SInclair
+Cambridge, UK
+
+email david@s-hull.org
+
+The software includes the S-hull programs.
+S-hull is copyrighted as above.
+S-hull is free software and may be obtained from www.s-hull.org.
+It may be freely copied, modified, 
+and redistributed under the following conditions:
+S-hull is free software and may be obtained from www.s-hull.org.
+It may be freely copied, modified, 
+and redistributed under the following conditions which might loosely be termed a contribtors beerware license:
+1. All copyright notices must remain intact in all files.
+2. A copy of this text file must be distributed along with any copies 
+   of S-hull that you redistribute; this includes copies that you have 
+   modified, or copies of programs or other software products that 
+   include S-hull where distributed as source.
+
+3. If you modify S-hull, you must include a notice giving the
+   name of the person performing the modification, the date of
+   modification, and the reason for such modification.
+
+4. If you are distributing a binary or compiled version of s-hull it
+           is not necessary to include any acknowledgement or reference
+           to s-hull.
+5. There is no warranty or other guarantee of fitness for S-hull, it is 
+   provided solely "as is".  Bug reports or fixes may be sent to 
+   bugs@s-hull.org; the authors may or may not act on them as 
+   they desire.
+6. By copying or compliing the code for S-hull you explicitly indemnify 
+the copyright holder against any liability he may incur as a result of you 
+copying the code.
+
+7. If you meet any of the contributors to the code you used from s-hull.org
+           in a pub or a bar, and you think the source code they contributed to is worth it,
+           you can buy them a beer.
+
+           If your principles run against beer a bacon-double-cheeseburger would do just as nicely
+           or you could email david@s-hull.org and arrange to make a donation of 10 of your local currancy units
+           to support s-hull.org.
+           
diff --git a/src/s_hull/s_hull.C b/src/s_hull/s_hull.C
new file mode 100755 (executable)
index 0000000..5fb1c1f
--- /dev/null
@@ -0,0 +1,1598 @@
+#include <iostream>
+#include <hash_set.h>
+#include <set>
+#include <vector>
+#include <fstream>
+#include <stdlib.h>
+#include <math.h>
+
+
+#include "s_hull.h"
+
+/*
+  fast and simple convex hull finder.
+  kind of a circular vesion of Steven Fortune's sweepline algorithm
+but without the complicated bits.
+
+  and combined with link insertion and flipping will give you Delaunay triangles..
+
+S-hull, Copyright (c) 2010
+Dr David SInclair
+Cambridge, UK
+
+email david@s-hull.org
+S-hull is free software and may be obtained from www.s-hull.org.
+It may be freely copied, modified, 
+and redistributed under the following conditions which might loosely be termed a contribtors beerware license:
+1. All copyright notices must remain intact in all files.
+2. A copy of this text file must be distributed along with any copies 
+   of S-hull that you redistribute; this includes copies that you have 
+   modified, or copies of programs or other software products that 
+   include S-hull where distributed as source.
+
+3. If you modify S-hull, you must include a notice giving the
+   name of the person performing the modification, the date of
+   modification, and the reason for such modification.
+
+4. If you are distributing a binary or compiled version of s-hull it
+           is not necessary to include any acknowledgement or reference
+           to s-hull.
+5. There is no warranty or other guarantee of fitness for S-hull, it is 
+   provided solely "as is".  Bug reports or fixes may be sent to 
+   bugs@s-hull.org; the authors may or may not act on them as 
+   they desire.
+6. By copying or compliing the code for S-hull you explicitly indemnify 
+the copyright holder against any liability he may incur as a result of you 
+copying the code.
+
+7. If you meet any of the contributors to the code you used from s-hull.org
+           in a pub or a bar, and you think the source code they contributed to is worth it,
+           you can buy them a beer.
+
+           If your principles run against beer a bacon-double-cheeseburger would do just as nicely
+           or you could email david@s-hull.org and arrange to make a donation of 10 of your local currancy units
+           to support s-hull.org.
+           
+
+ */
+
+
+
+
+
+void circle_cent2(float r1,float c1, float r2,float c2, float r3,float c3,
+float &r,float &c, float &ro2){
+  /*
+   *  function to return the center of a circle and its radius
+   * degenerate case should never be passed to this routine!!!!!!!!!!!!!
+   * but will return r0 = -1 if it is.
+   */
+   
+   float v1 = 2*(r2-r1), v2 = 2*(c2-c1), v3 = r2*r2 - r1*r1 + c2*c2 - c1*c1;
+   float v4 = 2*(r3-r1),
+   v5 = 2*(c3-c1),
+   v6 = r3*r3 - r1*r1 + c3*c3 - c1*c1,
+   
+   v7 =  v2*v4 - v1*v5;
+   if( v7 == 0 ){   
+      r=0;
+      c=0;
+      ro2 = -1;
+      return;
+   }
+   
+   c = (v4*v3 - v1*v6)/v7;
+   if( v1 != 0 )
+      r = (v3 - c*v2)/v1;
+   else
+      r = (v6 - c*v5)/v4;
+   
+   ro2 = ( (r-r1)*(r-r1) + (c-c1)*(c-c1) );
+   
+   return;
+}
+
+
+void write_Shx(std::vector<Shx> &pts, char * fname){
+   std::ofstream out(fname, ios::out);
+   
+   int nr = pts.size();
+   out << nr << " 2" << endl;
+   
+   for (int r = 0; r < nr; r++){
+     out << pts[r].r << ' ' << pts[r].c <<  endl;
+   }
+   out.close();
+   
+   return;
+};
+
+
+
+/*
+ write out triangle ids to be compatible with matlab/octave array numbering.
+
+ */
+void write_Triads(std::vector<Triad> &ts, char * fname){
+   std::ofstream out(fname, ios::out);
+   
+   int nr = ts.size();
+   out << nr << " 7" << endl;
+   
+   for (int r = 0; r < nr; r++){
+     out << ts[r].a+1 << ' ' << ts[r].b+1 <<' ' << ts[r].c+1 <<' ' 
+        << ts[r].ab+1 <<' ' << ts[r].ac+1 <<' ' << ts[r].bc+1 << " " << ts[r].ro <<  endl;
+   }
+   out.close();
+   
+   return;
+};
+
+
+
+
+void T_flip2( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, int numt, int start){
+
+  float R,C,r0,c0, r1,c1, r2,c2, r3,c3, rot, rot2, dR, dC;
+  int pa,pb,pc, pd, ab, bc, ac, D, L1, L2, L3, L4, T2;
+  std::vector<int> aliens;
+  Triad tx, tx2;
+  std::set<int> ids;
+
+  for( int t=start; t<numt; t++){
+
+    //write_Triads(triads, "tflip0.mat");
+
+    Triad &tri = triads[t];
+    // test all 3 neighbours of tri 
+    pa = slump[tri.a];
+    pb = slump[tri.b];
+    pc = slump[tri.c];
+
+    int flipped = 0;
+
+
+    if( tri.bc >= 0 ){
+      T2 = tri.bc;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.a == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.a == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.b == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 12 dude!" << endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ab;
+       L2 = tri.ac;    
+      
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+
+       tx.a = tri.a;
+       tx.b = tri.b;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.a;
+       tx2.b = tri.c;
+       tx2.c = D;
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+       
+       
+       ids.insert(t);
+       ids.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       flipped = 1;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+
+      }
+    }
+
+    //write_Triads(triads, "tflip1.mat");
+    int df = 9;
+    df = 8;
+  }
+
+
+
+
+
+
+  return;
+}
+
+
+/*  version in which the ids of the triangles associated with the sides of the hull are tracked.
+   
+
+ */
+
+void s_hull_del_ray2( std::vector<Shx> &pts, std::vector<Triad> &triads)
+{
+
+  int nump = pts.size();
+
+
+  float r = pts[0].r;
+  float c = pts[0].c;
+  for( int k=0; k<nump; k++){
+    float dr = pts[k].r-r;
+    float dc = pts[k].c-c;
+
+    pts[k].ro = dr*dr + dc*dc;
+
+  }
+
+  sort( pts.begin(), pts.end() );
+
+  
+  float r1 = pts[0].r;
+  float c1 = pts[0].c;
+
+  float r2 = pts[1].r;
+  float c2 = pts[1].c;
+  int mid = -1;
+  float romin2 = 100000000.0, ro2, R,C;
+
+  int k=2; 
+  while (k<nump){
+
+    circle_cent2(r1,c1,r2,c2,  pts[k].r,  pts[k].c, r,c,ro2);
+    if( ro2 < romin2 && ro2 > 0 ){
+      mid = k;
+      romin2 = ro2;
+      R = r;
+      C = c;
+
+    }
+    else if( romin2 *4 < pts[k].ro )
+      k=nump;
+
+    k++;
+  }
+
+  //std::cerr << "earwig noodles " << pts[1].id << " " << pts[mid].id << " " << romin2 << endl;
+
+  Shx pt0 = pts[0];
+  Shx pt1 = pts[1];
+  Shx pt2 = pts[mid];
+
+  pts.erase(pts.begin() + mid);  // necessary for round off reasons:((((((
+  pts.erase(pts.begin() );
+  pts.erase(pts.begin() );
+
+  for( int k=0; k<nump-3; k++){
+    float dr = pts[k].r-R;
+    float dc = pts[k].c-C;
+
+    pts[k].ro = dr*dr + dc*dc;
+
+  }
+
+  sort( pts.begin(), pts.end() );
+
+  pts.insert(pts.begin(), pt2);
+  pts.insert(pts.begin(), pt1);
+  pts.insert(pts.begin(), pt0);
+
+  int slump [nump];
+  
+  for( int k=0; k<nump; k++){
+    slump[ pts[k].id] = k;
+  }
+
+  std::vector<Shx> hull;
+  
+
+  r = (pts[0].r + pts[1].r + pts[2].r )/3.0;
+  c = (pts[0].c + pts[1].c + pts[2].c )/3.0;
+  
+  float dr0 = pts[0].r - r,  dc0 = pts[0].c - c;
+  float tr01 =  pts[1].r - pts[0].r, tc01 =  pts[1].c - pts[0].c;
+
+  float df = -tr01* dc0 + tc01*dr0;
+  if( df < 0 ){   // [ 0 1 2 ]
+    pt0.tr = pt1.r-pt0.r;
+    pt0.tc = pt1.c-pt0.c;    
+    pt0.trid = 0;
+    hull.push_back( pt0 );
+
+    pt1.tr = pt2.r-pt1.r;
+    pt1.tc = pt2.c-pt1.c;    
+    pt1.trid = 0;
+    hull.push_back( pt1 );
+
+    pt2.tr = pt0.r-pt2.r;
+    pt2.tc = pt0.c-pt2.c;
+    pt2.trid = 0;
+    hull.push_back( pt2 );
+
+    
+    Triad tri(pt0.id,pt1.id,pt2.id);
+    tri.ro = romin2;
+    tri.R = R;
+    tri.C = C;
+
+    triads.push_back(tri);
+
+  }
+  else{          // [ 0 2 1 ] as anti-clockwise turning is the work of the devil....
+    pt0.tr = pt2.r-pt0.r;
+    pt0.tc = pt2.c-pt0.c;  
+    pt0.trid = 0;
+    hull.push_back( pt0 );
+
+    pt2.tr = pt1.r-pt2.r;
+    pt2.tc = pt1.c-pt2.c;    
+    pt2.trid = 0;
+    hull.push_back( pt2 );
+
+    pt1.tr = pt0.r-pt1.r;
+    pt1.tc = pt0.c-pt1.c;
+    pt1.trid = 0;
+    hull.push_back( pt1 );
+
+    Triad tri(pt0.id,pt2.id,pt1.id);
+    tri.ro = romin2;
+    tri.R = R;
+    tri.C = C;
+    triads.push_back(tri);
+  }
+
+  // add new points into hull (removing obscured ones from the chain)
+  // and creating triangles....
+  // that will need to be flipped.
+
+  float dr, dc, rx,cx;
+  Shx  ptx;
+  int numt;
+
+  for( int k=3; k<nump; k++){
+    rx = pts[k].r;    cx = pts[k].c;
+    ptx.r = rx;
+    ptx.c = cx;
+    ptx.id = pts[k].id;
+
+    int numh = hull.size(), numh_old = numh;
+    dr = rx- hull[0].r;    dc = cx- hull[0].c;  // outwards pointing from hull[0] to pt.
+
+    if(0){
+    cerr << "numt = " << triads.size() << endl;
+    cerr << "ids = [ " ;
+    for(int g=0; g<numh; g++){
+      cerr << hull[g].id+1 << ' ' ;
+    }
+    cerr <<   hull[0].id+1 << "];" << endl;
+    
+
+    cerr << "trids = [ " ;
+    for(int g=0; g<numh; g++){
+      cerr << hull[g].trid+1 << ' ' ;
+    }
+    cerr <<   hull[0].trid+1 << "];" << endl;
+
+
+    cerr << "h_test = [ " ;
+    for(int g=0; g<numh-1; g++){
+      float gaf = -(hull[g+1].c-hull[g].c) * hull[g].tr + (hull[g+1].r-hull[g].r)*hull[g].tc;
+      cerr << gaf << ' ' ;
+    }
+    
+    cerr <<   -(hull[0].c-hull[numh-1].c) * hull[numh-1].tr + 
+               (hull[0].r-hull[numh-1].r)*hull[numh-1].tc << "];" << endl;
+
+    }
+
+
+    std::vector<int> pidx, tridx;
+    int hidx;  // new hull point location within hull.....
+
+
+    float df = -dc* hull[0].tr + dr*hull[0].tc;    // visibility test vector.
+    if( df < 0 ){  // starting with a visible hull facet !!!
+      int e1 = 1, e2 = numh;
+      hidx = 0;
+
+      // check to see if segment numh is also visible
+      df = -dc* hull[numh-1].tr + dr*hull[numh-1].tc;
+      //cerr << df << ' ' ;
+      if( df < 0 ){    // visible.
+       pidx.push_back(hull[numh-1].id);
+       tridx.push_back(hull[numh-1].trid);
+       
+
+       for( int h=0; h<numh-1; h++){
+         // if segment h is visible delete h
+         dr = rx- hull[h].r;    dc = cx- hull[h].c;
+         df = -dc* hull[h].tr + dr*hull[h].tc;
+         pidx.push_back(hull[h].id);
+         tridx.push_back(hull[h].trid);
+         if( df < 0 ){ 
+           hull.erase(hull.begin() + h);
+           h--;
+           numh--;
+         }
+         else{   // quit on invisibility
+           ptx.tr = hull[h].r - ptx.r;
+           ptx.tc = hull[h].c - ptx.c;
+
+           hull.insert( hull.begin() , ptx);
+           numh++;
+           break;
+         }
+       }
+       // look backwards through the hull structure.
+       
+       for( int h=numh-2; h>0; h--){
+         // if segment h is visible delete h + 1
+         dr = rx- hull[h].r;    dc = cx- hull[h].c;
+         df = -dc* hull[h].tr + dr*hull[h].tc;
+
+         if( df < 0 ){  // h is visible 
+           pidx.insert(pidx.begin(), hull[h].id);
+           tridx.insert(tridx.begin(), hull[h].trid);
+           hull.erase(hull.begin() + h+1);  // erase end of chain
+           
+         }
+         else{
+
+           h = hull.size()-1;
+           hull[h].tr = -hull[h].r + ptx.r;   // points at start of chain.
+           hull[h].tc = -hull[h].c + ptx.c;
+           break;
+         }
+       }
+
+       df = 9;
+
+      }
+      else{
+       //      cerr << df << ' ' << endl;
+       hidx = 1;  // keep pt hull[0]
+       tridx.push_back(hull[0].trid);
+       pidx.push_back(hull[0].id);
+
+       for( int h=1; h<numh; h++){
+         // if segment h is visible delete h  
+         dr = rx- hull[h].r;    dc = cx- hull[h].c;
+         df = -dc* hull[h].tr + dr*hull[h].tc;
+         pidx.push_back(hull[h].id);
+         tridx.push_back(hull[h].trid);
+         if( df < 0 ){                     // visible
+           hull.erase(hull.begin() + h);
+           h--;
+           numh--;
+         }
+         else{   // quit on invisibility
+           ptx.tr = hull[h].r - ptx.r;
+           ptx.tc = hull[h].c - ptx.c;
+
+           hull[h-1].tr = ptx.r - hull[h-1].r;
+           hull[h-1].tc = ptx.c - hull[h-1].c;
+
+           hull.insert( hull.begin()+h, ptx);
+           break;
+         }
+       }
+      }
+
+      df = 8;
+
+    }
+    else{
+      int e1 = -1,  e2 = numh;
+      for( int h=1; h<numh; h++){      
+       dr = rx- hull[h].r;    dc = cx- hull[h].c;
+       df = -dc* hull[h].tr + dr*hull[h].tc;
+       if( df < 0 ){
+         if( e1 < 0 ) e1 = h;  // fist visible
+       }
+       else{
+         if( e1 > 0 ){ // first invisible segment.
+           e2 = h;
+           break;
+         }
+       }
+
+      }
+
+
+      // triangle pidx starts at e1 and ends at e2 (inclusive).        
+      if( e2 < numh ){
+       for( int e=e1; e<=e2; e++){
+         pidx.push_back(hull[e].id);
+         tridx.push_back(hull[e].trid);
+       }
+      }
+      else{
+       for( int e=e1; e<e2; e++){
+         pidx.push_back(hull[e].id);
+         tridx.push_back(hull[e].trid);   // there are only n-1 triangles from n hull pts.
+       }
+       pidx.push_back(hull[0].id);
+      }
+
+
+      // erase elements e1+1 : e2-1 inclusive.
+      
+      if( e1 < e2-1){
+       hull.erase(hull.begin() + e1+1, hull.begin()+ e2); 
+      }
+
+      // insert ptx at location e1+1.
+      if( e2 == numh){
+       ptx.tr = hull[0].r - ptx.r;
+       ptx.tc = hull[0].c - ptx.c;
+      }
+      else{
+       ptx.tr = hull[e1+1].r - ptx.r;
+       ptx.tc = hull[e1+1].c - ptx.c;
+      }
+
+      hull[e1].tr = ptx.r - hull[e1].r;
+      hull[e1].tc = ptx.c - hull[e1].c;
+      
+      hull.insert( hull.begin()+e1+1, ptx);
+      hidx = e1+1;
+      
+    }
+
+
+    int a = ptx.id, T0;
+    Triad trx( a, 0,0);
+    r1 = pts[slump[a]].r;
+    c1 = pts[slump[a]].c;
+
+    int npx = pidx.size()-1;
+    numt = triads.size();
+    T0 = numt;
+
+    if( npx == 1){
+       trx.b = pidx[0];
+       trx.c = pidx[1];
+      
+      // compute circum circle radius squared (only relative size is required for flipping)
+      
+      r2 = pts[slump[trx.b]].r;
+      c2 = pts[slump[trx.b]].c;
+
+      circle_cent2(r1,c1,r2,c2, pts[slump[trx.c]].r,pts[slump[trx.c]].c , r,c,ro2);
+      trx.ro = ro2;
+      trx.R = r;
+      trx.C = c;
+
+      trx.bc = tridx[0];
+      trx.ab = -1;
+      trx.ac = -1;
+
+      // index back into the triads.
+      Triad &txx = triads[tridx[0]];
+      if( ( trx.b == txx.a && trx.c == txx.b) |( trx.b == txx.b && trx.c == txx.a)) {
+       txx.ab = numt;
+      }
+      else if( ( trx.b == txx.a && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.a)) {
+       txx.ac = numt;
+      }
+      else if( ( trx.b == txx.b && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.b)) {
+       txx.bc = numt;
+      }
+      
+
+      hull[hidx].trid = numt;
+      if( hidx > 0 )
+       hull[hidx-1].trid = numt;
+      else{
+       numh = hull.size();
+       hull[numh-1].trid = numt;
+      }
+      triads.push_back( trx );
+      numt++;
+    }
+    
+    else{
+      trx.ab = -1;
+      for(int p=0; p<npx; p++){
+       trx.b = pidx[p];
+       trx.c = pidx[p+1];
+      
+       // compute circum circle radius squared (only relative size is required for flipping)
+       
+       r2 = pts[slump[trx.b]].r;
+       c2 = pts[slump[trx.b]].c;
+       
+       circle_cent2(r1,c1,r2,c2, pts[slump[trx.c]].r,pts[slump[trx.c]].c , r,c,ro2);
+       trx.ro = ro2;
+       trx.R = r;
+       trx.C = c;
+       
+    
+       trx.bc = tridx[p];
+       if( p > 0 )
+         trx.ab = numt-1;
+       trx.ac = numt+1;
+       
+       // index back into the triads.
+       Triad &txx = triads[tridx[p]];
+       if( ( trx.b == txx.a && trx.c == txx.b) |( trx.b == txx.b && trx.c == txx.a)) {
+         txx.ab = numt;
+       }
+       else if( ( trx.b == txx.a && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.a)) {
+         txx.ac = numt;
+       }
+       else if( ( trx.b == txx.b && trx.c == txx.c) |( trx.b == txx.c && trx.c == txx.b)) {
+         txx.bc = numt;
+       }
+      
+       if( trx.ab == 26777 || trx.ac == 26777 || trx.bc == 26777){
+         int foon = 7;
+       }
+
+       triads.push_back( trx );
+       numt++;
+      }
+      triads[numt-1].ac=-1;
+
+      hull[hidx].trid = numt-1;
+      if( hidx > 0 )
+       hull[hidx-1].trid = T0;
+      else{
+       numh = hull.size();
+       hull[numh-1].trid = T0;
+      }
+
+
+    }
+
+
+    //    write_Triads(triads, "tris.mat");
+    //int dfx = 9;
+    //T_flip2( pts, triads, slump, numt, T0);
+  
+    //write_Triads(triads, "tris2.mat");
+
+  }
+
+  cerr << "of triangles " << triads.size() << " to be flipped. "<< endl;
+  //write_Triads(triads, "tris0.mat");
+
+  std::set<int> ids, ids2;
+  T_flip3( pts, triads, slump, numt, 0, ids);
+
+
+  int nits = ids.size(), nit=1;
+  while(  nits > 0 && nit < 20){
+    // char nam[128];
+    //sprintf(nam, "tris_%d.mat", nit);
+    //write_Triads(triads, nam);
+    
+    T_flip4( pts, triads, slump, ids);
+    nits = ids.size();
+    nit ++;
+    
+  }
+  //write_Triads(triads, "triangles3.mat");
+
+  return;
+}
+
+/*
+  flip pairs of triangles that are not valid delaunay triangles
+  (the test used is the circum circle not containing any point of the other triangle (in bad English))
+
+ */
+
+
+void T_flip3( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, int numt, int start, std::set<int> &ids){
+
+  float R,C,r0,c0, r1,c1, r2,c2, r3,c3, rot, rot2, dR, dC;
+  int pa,pb,pc, pd, ab, bc, ac, D, L1, L2, L3, L4, T2;
+  std::vector<int> aliens;
+  Triad tx, tx2;
+  //std::set<int> ids;
+
+  for( int t=start; t<numt; t++){
+
+    //write_Triads(triads, "tflip0.mat");
+
+    Triad &tri = triads[t];
+    // test all 3 neighbours of tri 
+
+    int flipped = 0;
+
+    if( tri.bc >= 0 ){
+
+      pa = slump[tri.a];
+      pb = slump[tri.b];
+      pc = slump[tri.c];
+
+      T2 = tri.bc;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.b == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.b == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.b == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 12 dude! " << t << endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ab;
+       L2 = tri.ac;    
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+
+       tx.a = tri.a;
+       tx.b = tri.b;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.a;
+       tx2.b = tri.c;
+       tx2.c = D;
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+       
+
+       ids.insert(t);
+       ids.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       flipped = 1;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+       }
+      }
+    }
+
+
+    if(  flipped == 0 && tri.ab >= 0 ){
+
+      pc = slump[tri.c];
+      pb = slump[tri.b];
+      pa = slump[tri.a];
+
+      T2 = tri.ab;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.a == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.a == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.a == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 13 dude! " << t << endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ac;
+       L2 = tri.bc;    
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+
+       tx.a = tri.c;
+       tx.b = tri.a;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.c;
+       tx2.b = tri.b;
+       tx2.c = D;
+       circle_cent2(pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+       
+
+       ids.insert(t);
+       ids.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       flipped = 1;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+
+       }
+
+      }
+    }
+
+
+    if( flipped == 0 && tri.ac >= 0 ){
+
+      pc = slump[tri.c];
+      pb = slump[tri.b];
+      pa = slump[tri.a];
+
+      T2 = tri.ac;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.a == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.a == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.a == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 14 dude! " << t << endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ab;   // .ac shared limb
+       L2 = tri.bc;    
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+
+       tx.a = tri.b;
+       tx.b = tri.a;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.b;
+       tx2.b = tri.c;
+       tx2.c = D;
+       circle_cent2(pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+       
+       ids.insert(t);
+       ids.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+
+       }
+      }
+    }
+
+    //write_Triads(triads, "tflip1.mat");
+    int df = 9;
+    df = 8;
+  }
+
+  
+  //  cerr << " triangles to resolve " << ids.size() << endl;
+
+
+
+
+
+  return;
+}
+
+
+
+
+
+
+// same again but with set of triangle ids to be iterated over.
+
+
+void T_flip4( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, std::set<int> &ids){
+
+  float R,C,r0,c0, r1,c1, r2,c2, r3,c3, rot, rot2, dR, dC;
+  int pa,pb,pc, pd, ab, bc, ac, D, L1, L2, L3, L4, T2;
+
+  Triad tx, tx2;
+  std::set<int> ids2;
+  ids2.clear();
+
+  std::set<int> :: const_iterator x=ids.begin();
+  while(x != ids.end() ){
+    int t = *x;
+    x++;
+    
+
+    Triad &tri = triads[t];
+    // test all 3 neighbours of tri 
+    int flipped = 0;
+
+   
+
+    if( tri.bc >= 0 ){
+
+      pa = slump[tri.a];
+      pb = slump[tri.b];
+      pc = slump[tri.c];
+
+      T2 = tri.bc;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.b == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.b == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.b == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 15 dude! t: " << t << "  T2: " <<  T2<<  endl;
+       //      tri.prnt();
+       //t2.prnt();
+
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ab;
+       L2 = tri.ac;    
+
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+      
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+
+       tx.a = tri.a;
+       tx.b = tri.b;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.a;
+       tx2.b = tri.c;
+       tx2.c = D;
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+               
+       ids2.insert(t);
+       ids2.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       flipped = 1;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+       //if( triads[26777].ab == 27004 && triads[26777].bc == 27004)
+       //  cerr << " feck 1 " << endl;
+       }
+      }
+    }
+
+
+    if( flipped == 0 && tri.ab >= 0 ){
+
+      pc = slump[tri.c];
+      pb = slump[tri.b];
+      pa = slump[tri.a];
+
+      T2 = tri.ab;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.a == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.a == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.a == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 16 dude! " << t <<  endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+
+      if( dR*dR+dC*dC < tri.ro ){  // not valid in the Delaunay sense.
+       L1 = tri.ac;
+       L2 = tri.bc;    
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+       circle_cent2(pts[pa].r, pts[pa].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+
+       tx.a = tri.c;
+       tx.b = tri.a;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.c;
+       tx2.b = tri.b;
+       tx2.c = D;
+       circle_cent2(pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+       
+       if( (tx.ab == 26777 && tx.ac == 26777 && tx.bc == 26777) || 
+           (tx2.ab == 26777 && tx2.ac == 26777 && tx2.bc == 26777) ){
+         int foon = 8;
+       }
+
+       
+       ids2.insert(t);
+       ids2.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       flipped = 1;
+
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+       ///if( triads[26777].ab == 27004 && triads[26777].bc == 27004)
+       //  cerr << " feck 2 " << endl;
+       }
+      }
+    }
+
+
+    if( flipped == 0 && tri.ac >= 0 ){
+
+      pc = slump[tri.c];
+      pb = slump[tri.b];
+      pa = slump[tri.a];
+
+      T2 = tri.ac;
+      Triad &t2 = triads[T2];
+      // find relative orientation (shared limb).
+      if( t2.ab == t ){
+       D = t2.c;
+       pd = slump[t2.c];
+
+       if( tri.a == t2.a){
+         L3 = t2.ac;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ac;
+       }
+      }
+      else if(  t2.ac == t ){
+       D = t2.b;
+       pd = slump[t2.b];
+       
+       if( tri.a == t2.a){
+         L3 = t2.ab;
+         L4 = t2.bc;
+       }
+       else{
+         L3 = t2.bc;
+         L4 = t2.ab;
+       }
+      }
+      else if(  t2.bc == t ){
+       D = t2.a;
+       pd = slump[t2.a];
+       
+       if( tri.a == t2.b){
+         L3 = t2.ab;
+         L4 = t2.ac;
+       }
+       else{
+         L3 = t2.ac;
+         L4 = t2.ab;
+       }
+      }
+      else{
+       cerr << "fuck up at line 17 dude! " << t << endl;
+      }
+
+      r3 = pts[pd].r;
+      c3 = pts[pd].c;
+      dR = tri.R-r3;
+      dC = tri.C-c3;
+      
+      float scubit = dR*dR+dC*dC - tri.ro;
+
+      if( scubit < 0.0 ){  // not valid in the Delaunay sense.
+       L1 = tri.ab;   // .ac shared limb
+       L2 = tri.bc;    
+       if( L1 != L3 && L2 != L4 ){  // need this check for stability.
+
+       if( -scubit*1000 > tri.ro )
+         circle_cent2(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+       else{
+         circle_cent4(pts[pa].r, pts[pa].c, pts[pb].r, pts[pb].c, r3, c3, R, C , rot);
+         //cerr << "duff " << t << " scubit " << scubit << endl;
+       }
+
+       tx.a = tri.b;
+       tx.b = tri.a;
+       tx.c = D;
+       tx.ro = rot;
+       tx.R = R;
+       tx.C = C;
+       
+       tx.ab = L1;
+       tx.ac = T2;
+       tx.bc = L3;
+       
+       
+       // triangle 2;
+       tx2.a = tri.b;
+       tx2.b = tri.c;
+       tx2.c = D;
+
+
+       if( -scubit*1000 > tri.ro )
+         circle_cent2(pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+       else{
+         circle_cent2(pts[pb].r, pts[pb].c, pts[pc].r, pts[pc].c, r3, c3, R, C , rot);
+         //cerr << "duff " << t << " scubit " << scubit << endl;
+       }
+
+       tx2.ro = rot;
+       tx2.R = R;
+       tx2.C = C;
+       
+       tx2.ab = L2;
+       tx2.ac = t;
+       tx2.bc = L4;
+
+
+       ids2.insert(t);
+       ids2.insert(T2);
+       
+       t2 = tx2;
+       tri = tx;
+       
+       // change knock on triangle labels.
+       if( L3 >= 0 ){
+         Triad &t3 = triads[L3];
+         if( t3.ab == T2 ) t3.ab = t;
+         else if( t3.bc == T2 ) t3.bc = t;
+         else if( t3.ac == T2 ) t3.ac = t;
+       }
+       
+       if(L2 >= 0 ){
+         Triad &t4 = triads[L2];
+         if( t4.ab == t ) t4.ab = T2;
+         else if( t4.bc == t ) t4.bc = T2;
+         else if( t4.ac == t ) t4.ac = T2;
+       }
+
+       //if( triads[26777].ab == 27004 && triads[26777].bc == 27004)
+       //  cerr << " feck 3" << endl;
+       }
+      }
+    }
+
+    //write_Triads(triads, "tflip1.mat");
+    int df = 9;
+    df = 8;
+  }
+
+  
+  //  cerr << " triangles to resolve " << ids2.size() << endl;
+  ids.clear();
+  ids.insert(ids2.begin(), ids2.end());
+
+  return;
+}
+
+void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,
+                 float &r,float &c, float &ro2){
+  /*
+   *  function to return the center of a circle and its radius
+   * degenerate case should never be passed to this routine!!!!!!!!!!!!!
+   * but will return r0 = -1 if it is.
+   */
+  
+  double rd, cd;
+  double v1 = 2*(r2-r1), v2 = 2*(c2-c1), v3 = r2*r2 - r1*r1 + c2*c2 - c1*c1;
+  double v4 = 2*(r3-r1),
+    v5 = 2*(c3-c1),
+    v6 = r3*r3 - r1*r1 + c3*c3 - c1*c1,
+    
+    v7 =  v2*v4 - v1*v5;
+  if( v7 == 0 ){   
+    r=0;
+    c=0;
+    ro2 = -1;
+    return;
+  }
+  
+  cd = (v4*v3 - v1*v6)/v7;
+  if( v1 != 0 )
+    rd = (v3 - c*v2)/v1;
+  else
+    rd = (v6 - c*v5)/v4;
+  
+  ro2 = (float)  ( (rd-r1)*(rd-r1) + (cd-c1)*(cd-c1) );
+  r = (float) rd;
+  c = (float) cd;
+
+  return;
+}
diff --git a/src/s_hull/s_hull.h b/src/s_hull/s_hull.h
new file mode 100644 (file)
index 0000000..d2060eb
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef _structures_h
+#define _structures_h
+
+
+
+
+// for FILE
+
+#include <stdlib.h>
+#include <vector>
+#include <set>
+
+
+
+/* 
+   for use in s_hull.C
+
+S-hull, Copyright (c) 2010
+Dr David SInclair
+Cambridge, UK
+
+email david@s-hull.org
+
+The software includes the S-hull programs.
+S-hull is copyrighted as above.
+S-hull is free software and may be obtained from www.s-hull.org.
+It may be freely copied, modified, 
+and redistributed under the following conditions:
+
+S-hull is free software and may be obtained from www.s-hull.org.
+It may be freely copied, modified, 
+and redistributed under the following conditions which might loosely be termed a contribtors beerware license:
+1. All copyright notices must remain intact in all files.
+2. A copy of this text file must be distributed along with any copies 
+   of S-hull that you redistribute; this includes copies that you have 
+   modified, or copies of programs or other software products that 
+   include S-hull where distributed as source.
+
+3. If you modify S-hull, you must include a notice giving the
+   name of the person performing the modification, the date of
+   modification, and the reason for such modification.
+
+4. If you are distributing a binary or compiled version of s-hull it
+           is not necessary to include any acknowledgement or reference
+           to s-hull.
+5. There is no warranty or other guarantee of fitness for S-hull, it is 
+   provided solely "as is".  Bug reports or fixes may be sent to 
+   bugs@s-hull.org; the authors may or may not act on them as 
+   they desire.
+6. By copying or compliing the code for S-hull you explicitly indemnify 
+the copyright holder against any liability he may incur as a result of you 
+copying the code.
+
+7. If you meet any of the contributors to the code you used from s-hull.org
+           in a pub or a bar, and you think the source code they contributed to is worth it,
+           you can buy them a beer.
+
+           If your principles run against beer a bacon-double-cheeseburger would do just as nicely
+           or you could email david@s-hull.org and arrange to make a donation of 10 of your local currancy units
+           to support s-hull.org.
+           
+
+*/
+
+struct Triad
+{
+  int a,b, c;
+  int ab, bc, ac;  // adjacent edges index to neighbouring triangle.
+  float ro, R,C;
+  //std::set<int> idx;
+  Triad() {};
+Triad(int x, int y) : a(x), b(y),c(0), ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {};
+Triad(int x, int y, int z) : a(x), b(y), c(z),  ab(-1), bc(-1), ac(-1), ro(-1), R(0), C(0) {};
+Triad(const Triad &p) : a(p.a), b(p.b), c(p.c), ab(p.ab), bc(p.bc), ac(p.ac), ro(p.ro), R(p.R), C(p.C) {};
+
+  Triad &operator=(const Triad &p)
+  {
+    a = p.a;
+    b = p.b;
+    c = p.c;
+
+    ab = p.ab;
+    bc = p.bc;
+    ac = p.ac;
+
+    ro = p.ro;
+    R = p.R;
+    C = p.C;
+
+    return *this;
+  };
+  void prnt(){
+    cerr << a << " " << b << " " << c << "   " << ab << " " << ac << " " << bc << endl;
+  };
+};
+
+
+
+/* point structure for s_hull only.
+   has to keep track of triangle ids as hull evolves.
+
+
+*/
+
+
+struct Shx
+{
+  int id, trid;
+  float r,c , tr, tc;
+  float ro;
+  Shx() {};
+  Shx(int a, int b) : r(a), c(b), ro(0), id(-1) {}; 
+  Shx(int a, int b, float x) : r(a), c(b), ro(x), id(-1) {};
+  Shx(const Shx &p) : id(p.id), trid(p.trid), r(p.r), c(p.c), tr(p.tr), tc(p.tc), ro(p.ro) {};
+
+  Shx &operator=(const Shx &p)
+  {
+    id = p.id;
+    trid = p.trid;
+    r = p.r;
+    c = p.c;
+    tr = p.tr;
+    tc = p.tc;
+    ro = p.ro;
+    return *this;
+  };
+
+};
+
+//inline bool operator==(const Shx &a, const Shx &b) 
+//{ 
+//  return a.r == b.r && a.c == b.c;
+//};
+
+// sort into descending order (for use in corner responce ranking).
+inline bool operator<(const Shx &a, const Shx &b) 
+{ 
+  if( a.ro == b.ro)
+    return a.r < b.r;
+  return a.ro <  b.ro;
+};
+
+
+
+// from s_hull.C
+
+
+void s_hull_del_ray2( std::vector<Shx> &pts, std::vector<Triad> &triads);
+void circle_cent2(float r1,float c1, float r2,float c2, float r3,float c3,float &r,float &c, float &ro2);
+void circle_cent4(float r1,float c1, float r2,float c2, float r3,float c3,float &r,float &c, float &ro2);
+void write_Shx(std::vector<Shx> &pts, char * fname);
+void write_Triads(std::vector<Triad> &ts, char * fname);
+void T_flip2( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, int numt, int start);
+void T_flip3( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, int numt, int start,std::set<int> &ids );
+void T_flip4( std::vector<Shx> &pts, std::vector<Triad> &triads, int *slump, std::set<int> &ids);
+
+
+
+#endif
index 22c6f3606698e0898a8f99a1554ed207054df61d..63656d586fb71a8b91db318243fd87820e82539b 100644 (file)
@@ -1381,7 +1381,7 @@ colors for filling and boundary (second one if style @samp{@@} is used, black co
 @cindex Label
 @cindex fgets
 
-These functions draw the text. There are functions for drawing text in arbitrary place, in arbitrary direction and along arbitrary curve. MathGL can use arbitrary font-faces and parse many TeX commands (for more details see @ref{Font styles}). All these functions have 2 variant: for printing 8-bit text (@code{char *}) and for printing Unicode text (@code{wchar_t *}). In first case the conversion into the current locale is used. So sometimes you need to specify it by @code{setlocale()} function. The size argument control the size of text: if positive it give the value, if negative it give the value relative to @var{SetFontSize()}. The font type (STIX, arial, courier, times and so on) can be selected by function LoadFont(). @xref{Font settings}.
+These functions draw the text. There are functions for drawing text in arbitrary place, in arbitrary direction and along arbitrary curve. MathGL can use arbitrary font-faces and parse many TeX commands (for more details see @ref{Font styles}). All these functions have 2 variant: for printing 8-bit text (@code{char *}) and for printing Unicode text (@code{wchar_t *}). In first case the conversion into the current locale is used. So sometimes you need to specify it by @code{setlocale()} function. The size argument control the size of text: if positive it give the value, if negative it give the value relative to @code{SetFontSize()}. The font type (STIX, arial, courier, times and so on) can be selected by function LoadFont(). @xref{Font settings}.
 
 The font parameters are described by string. This string may set the text color @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}). Also,  after delimiter symbol @samp{:}, it can contain characters of font type (@samp{rbiwou}) and/or align (@samp{LRC}) specification. The font types are: @samp{r} -- roman (or regular) font, @samp{i} -- italic style, @samp{b} -- bold style, @samp{w} -- wired style, @samp{o} -- over-lined text, @samp{u} -- underlined text. By default roman font is used. The align types are: @samp{L} -- align left (default), @samp{C} -- align center, @samp{R} -- align right. For example, string @samp{b:iC} correspond to italic font style for centered text which printed by blue color.
 
@@ -2200,7 +2200,7 @@ The function draws grid lines for density plot of surface specified parametrical
 @cindex Cloud
 @cindex Beam
 
-These functions perform plotting of 3D data. 3D means that data depend from 3 independent parameters like matrix @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}.By default (if absent) values of @var{x}, @var{y}, @var{z} are equidistantly distributed in axis range. The minor dimensions of arrays @var{x}, @var{y}, @var{z}, @var{a} should be equal @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} or @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Arrays @var{x}, @var{y} and @var{z} can be vectors (not matrices as @var{a}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}). @sref{3D samples}
+These functions perform plotting of 3D data. 3D means that data depend from 3 independent parameters like matrix @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}. By default (if absent) values of @var{x}, @var{y}, @var{z} are equidistantly distributed in axis range. The minor dimensions of arrays @var{x}, @var{y}, @var{z}, @var{a} should be equal @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} or @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Arrays @var{x}, @var{y} and @var{z} can be vectors (not matrices as @var{a}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}). @sref{3D samples}
 
 @anchor{surf3}
 @deftypefn {MGL command} {} surf3 adat @code{val} ['sch'='']
@@ -2234,7 +2234,7 @@ Draws @var{num}-th uniformly distributed in color range isosurfaces for 3d data.
 @deftypefnx {C function} @code{void} mgl_cloud (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_cloud_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws cloud plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). This plot is a set of cubes with color and transparency proportional to value of @var{a}. The resulting plot is like cloud -- low value is transparent but higher ones are not. The number of plotting cells depend on @ref{MeshNum}. If string @var{sch} contain symbol @samp{.} then lower quality plot will produced with much low memory usage. If string @var{sch} contain symbol @samp{!} then transparency will be inversed, i.e. higher become transparent and lower become not transparent. See also @ref{surf3}. @sref{Cloud sample}
+The function draws cloud plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). This plot is a set of cubes with color and transparency proportional to value of @var{a}. The resulting plot is like cloud -- low value is transparent but higher ones are not. The number of plotting cells depend on @ref{MeshNum}. If string @var{sch} contain symbol @samp{.} then lower quality plot will produced with much low memory usage. If string @var{sch} contain symbol @samp{!} then transparency will be inversed, i.e. higher become transparent and lower become not transparent. See also @ref{surf3}, @ref{meshnum}. @sref{Cloud sample}
 @end deftypefn
 
 @anchor{dens3}
@@ -2323,7 +2323,6 @@ Draws the isosurface for 3d array @var{a} at constant values of @var{a}=@var{val
 @c ##################################################################
 @node Dual plotting, Vector fields, 3D plotting, MathGL core
 @section Dual plotting
-
 @cindex SurfC
 @cindex SurfA
 @cindex Surf3C
@@ -2391,7 +2390,7 @@ The function draws surface specified parametrically @{@var{x}[i,j], @var{y}[i,j]
 @deftypefnx {C function} @code{void} mgl_surf3a_val (@code{HMGL} gr, @code{float} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_surf3a_xyz_val (@code{HMGL} gr, @code{float} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. It is mostly the same as @ref{surf3} function but the color of isosurface depends on values of array @var{c}. If string contain @samp{#} then wire plot is produced. See also @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3C sample}
+The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. It is mostly the same as @ref{surf3} function but the color of isosurface depends on values of array @var{c}. If string contain @samp{#} then wire plot is produced. See also @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3A sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} surf3a adat cdat ['sch'='']
@@ -2438,14 +2437,13 @@ The function draws mapping plot for matrices @{@var{ax}, @var{ay} @} which param
 @deftypefnx {C function} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-Draws spectrogram of complex array @var{re}+i*@code{im} for Fourier size of @var{dn} points at plane @var{z}=@var{Min}.z. For example in 1D case, result is density plot of data @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} with size @{int(nx/dn), dn, ny@}. At this array @var{re}, @var{im} parametrically depend on coordinates @var{x}, @var{y}. The size of @var{re} and @var{im} must be the same. The minor dimensions of arrays @var{x}, @var{y}, @var{re} should be equal. Arrays @var{x}, @var{y} can be vectors (not matrix as @var{re}).  @sref{STFA sample}
+Draws spectrogram of complex array @var{re}+i*@var{im} for Fourier size of @var{dn} points at plane @var{z}=@var{Min}.z. For example in 1D case, result is density plot of data @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} with size @{int(nx/dn), dn, ny@}. At this array @var{re}, @var{im} parametrically depend on coordinates @var{x}, @var{y}. The size of @var{re} and @var{im} must be the same. The minor dimensions of arrays @var{x}, @var{y}, @var{re} should be equal. Arrays @var{x}, @var{y} can be vectors (not matrix as @var{re}).  @sref{STFA sample}
 @end deftypefn
 
 
 @c ##################################################################
 @node Vector fields, Other plotting, Dual plotting, MathGL core
 @section Vector fields
-
 @cindex Traj
 @cindex Vect
 @cindex Dew
@@ -2464,7 +2462,7 @@ These functions perform plotting of 2D and 3D vector fields. There are 5 general
 @deftypefnx {C function} @code{void} mgl_traj_xyz (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}z, @code{HCDT}ax, @code{HCDT}ay, @code{HCDT}az, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_traj_xy (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}ax, @code{HCDT}ay, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws vectors @{@var{ax}, @var{ay}, @var{az}@} along a curve @{@var{x}, @var{y}, @var{z}@}. The length of arrows are proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}. String @var{pen} specifies the color (see @ref{Line styles}). By default (@code{pen=""}) color from palette is used (see @ref{Palette and colors}). Parameter @var{len} set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if @var{len}=0). The minor sizes of all arrays must be equal and large 2. The plots are drawn for each row if one of the data is the matrix. See also @ref{vect}. @sref{Traj sample}
+The function draws vectors @{@var{ax}, @var{ay}, @var{az}@} along a curve @{@var{x}, @var{y}, @var{z}@}. The length of arrows are proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}. String @var{pen} specifies the color (see @ref{Line styles}). By default (@code{pen=""}) color from palette is used (see @ref{Palette and colors}). Option @var{value} set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if @var{value}=0). The minor sizes of all arrays must be equal and large 2. The plots are drawn for each row if one of the data is the matrix. See also @ref{vect}. @sref{Traj sample}
 @end deftypefn
 
 @anchor{vect}
@@ -2581,7 +2579,7 @@ This is 3D version of the previous functions.
 @deftypefnx {C function} @code{void} mgl_grad_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_grad_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
-The function draws gradient lines for scalar field @var{phi}[i,j,k] specified parametrically @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Number of lines is proportional to @var{value} option (default is 5). If @var{value}<0 then lines start only from edges of axis range. Warm color corresponds to normal flow (like minimum). Cold one corresponds to inverse flow (like maximum). If string @var{sch} contain symbol @samp{v} then arrows are drawn on flow threads. See also @ref{dens}, @ref{cont}, @ref{flow}.
+The function draws gradient lines for scalar field @var{phi}[i,j] (or @var{phi}[i,j,k] in 3d case) specified parametrically @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Number of lines is proportional to @var{value} option (default is 5). If @var{value}<0 then lines start only from edges of axis range. Warm color corresponds to normal flow (like minimum). Cold one corresponds to inverse flow (like maximum). If string @var{sch} contain symbol @samp{v} then arrows are drawn on flow threads. See also @ref{dens}, @ref{cont}, @ref{flow}.
 @end deftypefn
 
 @anchor{pipe}
@@ -2593,7 +2591,7 @@ The function draws gradient lines for scalar field @var{phi}[i,j,k] specified pa
 @deftypefnx {C function} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
 @deftypefnx {C function} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
 @end ifclear
-The function draws flow pipes for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} = @var{Min}.z. Number of pipes is proportional to @var{value} option (default is 5). If @samp{#} symbol is specified then pipes start only from edges of axis range. The color of lines is proportional to @math{\sqrt@{ax^2+ay^2@}}. Warm color corresponds to normal flow (like attractor). Cold one corresponds to inverse flow (like source). Parameter @var{r0} set the base pipe radius. If @var{r0}<0 or symbol @samp{i} is specified then pipe radius is inverse proportional to amplitude. The size of @var{ax} and @var{ay} must be equal. The minor dimensions of arrays @var{x}, @var{y} and @var{ax} must be equal too. Arrays @var{x} and @var{y} can be vectors (not matrices as @var{ax}). The vector field is plotted for each z slice of @var{ax}, @var{ay}. See also @ref{flow}, @ref{vect}. @sref{Pipe sample}
+The function draws flow pipes for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} = @var{Min}.z. Number of pipes is proportional to @var{value} option (default is 5). If @samp{#} symbol is specified then pipes start only from edges of axis range. The color of lines is proportional to @math{\sqrt@{ax^2+ay^2@}}. Warm color corresponds to normal flow (like attractor). Cold one corresponds to inverse flow (like source). Parameter @var{r0} set the base pipe radius. If @var{r0}<0 or symbol @samp{i} is specified then pipe radius is inverse proportional to amplitude. The vector field is plotted for each z slice of @var{ax}, @var{ay}. See also @ref{flow}, @ref{vect}. @sref{Pipe sample}
 @end deftypefn
 
 @deftypefn {MGL command} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
@@ -2611,7 +2609,6 @@ This is 3D version of the first functions. Here arrays @var{ax}, @var{ay}, @var{
 @c ##################################################################
 @node Other plotting, Nonlinear fitting, Vector fields, MathGL core
 @section Other plotting
-
 @cindex DensXYZ
 @cindex ContXYZ
 @cindex ContFXYZ
@@ -2620,7 +2617,8 @@ This is 3D version of the first functions. Here arrays @var{ax}, @var{ay}, @var{
 @cindex TriPlot
 @cindex TriCont
 @cindex QuadPlot
-@cindex Plots by formula
+@cindex FPlot
+@cindex FSurf
 
 These functions perform miscellaneous plotting. There is unstructured data points plots (Dots), surface reconstruction (Crust), surfaces on the triangular or quadrangular mesh (TriPlot, TriCont, QuadPlot), textual formula plotting (Plots by formula), data plots at edges (Dens[XYZ], Cont[XYZ], ContF[XYZ]). Each type of plotting has similar interface. There are 2 kind of versions which handle the arrays of data and coordinates or only single data array. Parameters of color scheme are specified by the string argument. @xref{Color scheme}.
 
index ea75cb6a6deb380cfcdf62dc505ef5c893d142b8..bca21a5cfb45cb75736cedc98e93d594e4239be9 100644 (file)
@@ -102,7 +102,7 @@ MGL не требует создания данного типа объекто
 Эти функции и переменные настраивают тип и степень прозрачности поверхностей. Главной является функция @code{Alpha()}, которая включает/выключает прозрачность для всех графиков, созданных после вызова @code{Alpha()} (за исключением mglGraphGL). Функция @code{SetAlphaDef} устанавливает величину alpha-канала по умолчанию. Прозрачность можно выключить для отдельного графика с помощью @code{SetTransparent}. Наконец, функция @code{SetTranspType} задает тип прозрачности. @sref{Transparency and lighting}
 
 @anchor{alpha}
-@deftypefn {MGL command} {} alpha @code{[val=on]}
+@deftypefn {Команда MGL} {} alpha @code{[val=on]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Alpha (@code{bool} enable)
 @deftypefnx {Функция С} @code{void} mgl_set_alpha (@code{HMGL} gr, @code{int} enable)
@@ -111,7 +111,7 @@ MGL не требует создания данного типа объекто
 @end deftypefn
 
 @anchor{alphadef}
-@deftypefn {MGL command} {} alphadef @code{val}
+@deftypefn {Команда MGL} {} alphadef @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAlphaDef (@code{float} val)
 @deftypefnx {Функция С} @code{void} mgl_set_alpha_default (@code{HMGL} gr, @code{float} alpha)
@@ -120,7 +120,7 @@ MGL не требует создания данного типа объекто
 @end deftypefn
 
 @anchor{transptype}
-@deftypefn {MGL command} {} transptype @code{val}
+@deftypefn {Команда MGL} {} transptype @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTranspType (@code{int} type)
 @deftypefnx {Функция С} @code{void} mgl_set_transp_type (@code{HMGL} gr, @code{int} type)
@@ -141,7 +141,7 @@ MGL не требует создания данного типа объекто
 Эти функции настраивают освещение графика. Главная функция @code{Light(bool)} включает/выключает освещение графиков построенных после ее вызова (в OpenGL работает сразу для всего рисунка). MathGL  поддерживает до 10 независимых источников света. Но в режиме OpenGL можно использовать только первые 8 из них. Положение, цвет, яркость каждого источника света можно задавать по отдельности. По умолчанию включен только первый (с порядковым номером @code{0}) источник света белого цвета, расположенный сверху.
 
 @anchor{light}
-@deftypefn {MGL command} {} light @code{[val=on]}
+@deftypefn {Команда MGL} {} light @code{[val=on]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{bool} Light (@code{bool} enable)
 @deftypefnx {Функция С} @code{void} mgl_set_light (@code{HMGL} gr, @code{int} enable)
@@ -149,7 +149,7 @@ MGL не требует создания данного типа объекто
 Включает/выключает освещение графика и возвращает предыдущее состояние. По умолчанию освещение выключено.
 @end deftypefn
 
-@deftypefn {MGL command} {} light @code{num} @code{val}
+@deftypefn {Команда MGL} {} light @code{num} @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Light (@code{int} n, @code{bool} enable)
 @deftypefnx {Функция С} @code{void} mgl_set_light_n (@code{HMGL} gr, @code{int} n, @code{int} enable)
@@ -157,8 +157,8 @@ MGL не требует создания данного типа объекто
 Включает/выключает @var{n}-ый источник света.
 @end deftypefn
 
-@deftypefn {MGL command} {} light @code{num xdir ydir zdir} ['col'='w' @code{br=0.5}]
-@deftypefnx {MGL command} {} light @code{num xdir ydir zdir xpos ypos zpos} ['col'='w' @code{br=0.5}]
+@deftypefn {Команда MGL} {} light @code{num xdir ydir zdir} ['col'='w' @code{br=0.5}]
+@deftypefnx {Команда MGL} {} light @code{num xdir ydir zdir xpos ypos zpos} ['col'='w' @code{br=0.5}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{float} bright=@code{0.5}, @code{float} ap=@code{0})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} r, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{float} bright=@code{0.5}, @code{float} ap=@code{0})
@@ -178,7 +178,7 @@ MGL не требует создания данного типа объекто
 @end ifclear
 
 @anchor{ambient}
-@deftypefn {MGL command} {} ambient @code{val}
+@deftypefn {Команда MGL} {} ambient @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAmbient (@code{float} bright=@code{0.5})
 @deftypefnx {Функция С} @code{void} mgl_set_ambbr (@code{HMGL} gr, @code{float} bright)
@@ -192,7 +192,7 @@ MGL не требует создания данного типа объекто
 @cindex Fog
 
 @anchor{fog}
-@deftypefn {MGL command} {} fog @code{val [dz=0.25]}
+@deftypefn {Команда MGL} {} fog @code{val [dz=0.25]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Fog (@code{float} d, @code{float} dz=@code{0.25})
 @deftypefnx {Функция С} @code{void} mgl_set_fog (@code{HMGL} gr, @code{float} d, @code{float} dz)
@@ -218,7 +218,7 @@ MGL не требует создания данного типа объекто
 Эти функции задают величины большинства параметров графика, включая размеры маркеров, стрелок, толщину линий и т.д. Как и любые другие настройки, они подействуют только на графики созданные после изменения настроек.
 
 @anchor{barwidth}
-@deftypefn {MGL command} {} barwidth @code{val}
+@deftypefn {Команда MGL} {} barwidth @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetBarWidth ( @code{float} val)
 @deftypefnx {Функция С} @code{void} mgl_set_bar_width (@code{HMGL} gr, @code{float} val)
@@ -227,7 +227,7 @@ MGL не требует создания данного типа объекто
 @end deftypefn
 
 @anchor{marksize}
-@deftypefn {MGL command} {} marksize @code{val}
+@deftypefn {Команда MGL} {} marksize @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMarkSize (@code{float} val)
 @deftypefnx {Функция С} @code{void} mgl_set_mark_size (@code{HMGL} gr, @code{float} val)
@@ -236,7 +236,7 @@ MGL не требует создания данного типа объекто
 @end deftypefn
 
 @anchor{arrowsize}
-@deftypefn {MGL command} {} arrowsize @code{val}
+@deftypefn {Команда MGL} {} arrowsize @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetArrowSize (@code{float} val)
 @deftypefnx {Функция С} @code{void} mgl_set_arrow_size (@code{HMGL} gr, @code{float} val)
@@ -246,7 +246,7 @@ MGL не требует создания данного типа объекто
 
 @anchor{meshnum}
 @anchor{MeshNum}
-@deftypefn {MGL command} {} meshnum @code{val}
+@deftypefn {Команда MGL} {} meshnum @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMeshNum (@code{int} val)
 @deftypefnx {Функция С} @code{void} mgl_set_meshnum (@code{HMGL} gr, @code{int} num)
@@ -267,7 +267,7 @@ MGL не требует создания данного типа объекто
 Эти функции задают условия когда точка будет исключена (вырезана) из рисования. Замечу, что все точки со значением(-ями) NAN по одной из координат или амплитуде автоматически исключаются из рисования. @sref{Cutting sample}
 
 @anchor{cut}
-@deftypefn {MGL command} {} cut @code{val}
+@deftypefn {Команда MGL} {} cut @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCut (@code{bool} val)
 @deftypefnx {Функция С} @code{void} mgl_set_cut (@code{HMGL} gr, @code{int} val)
@@ -275,7 +275,7 @@ MGL не требует создания данного типа объекто
 Задает обрезание точек за пределами осей координат. Если @code{true} то такие точки исключаются из рисования (это по умолчанию) иначе они проецируются на ограничивающий прямоугольник.
 @end deftypefn
 
-@deftypefn {MGL command} {} cut @code{x1 y1 z1 x2 y2 z2}
+@deftypefn {Команда MGL} {} cut @code{x1 y1 z1 x2 y2 z2}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCutBox (@code{mglPoint} p1, @code{mglPoint} p1)
 @deftypefnx {Функция С} @code{void} mgl_set_cut_box (@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} x2, @code{float} y2, @code{float} z2)
@@ -283,7 +283,7 @@ MGL не требует создания данного типа объекто
 Задает границы параллелепипеда внутри которого точки не рисуются. Если границы одинаковы (переменные равны), то параллелепипеда считается пустым. @sref{CutMinMax sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} cut 'cond'
+@deftypefn {Команда MGL} {} cut 'cond'
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} CutOff (@code{const char *}cond)
 @deftypefnx {Функция С} @code{void} mgl_set_cutoff (@code{HMGL} gr, @code{const char *}cond)
@@ -309,12 +309,12 @@ MGL не требует создания данного типа объекто
 @cindex RotateText
 
 @anchor{font}
-@deftypefn {MGL command} {} font 'fnt' [@code{val=6}]
+@deftypefn {Команда MGL} {} font 'fnt' [@code{val=6}]
 Задает стиль и размер шрифта (см. @ref{Text printing}). Вначале используется @samp{:rC} -- прямой шрифт с выравниванием по центру. По умолчанию размер подписей оси координат в 1.4 раза больше. См. также см. @ref{Font styles}.
 @end deftypefn
 
 @anchor{rotatetext}
-@deftypefn {MGL command} {} rotatetext @code{val}
+@deftypefn {Команда MGL} {} rotatetext @code{val}
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRotatedText (@code{bool} val)
 @deftypefnx {Функция С} @code{void} mgl_set_rotated_text (@code{HMGL} gr, @code{int} val)
 Включает/выключает вращение меток и подписей осей координат вдоль оси.
@@ -367,7 +367,7 @@ MGL не требует создания данного типа объекто
 @cindex Palette
 
 @anchor{palette}
-@deftypefn {MGL command} {} palette 'colors'
+@deftypefn {Команда MGL} {} palette 'colors'
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetPalette (@code{const char *}@var{colors})
 @deftypefnx {Функция С} @code{void} mgl_set_palette (@code{HMGL} gr, @code{const char *}@var{colors})
@@ -465,10 +465,10 @@ Setsize: размер(ы) равны нулю или отрицательны
 @anchor{yrange}
 @anchor{zrange}
 @anchor{crange}
-@deftypefn {MGL command} {} xrange @code{v1 v2}
-@deftypefnx {MGL command} {} yrange @code{v1 v2}
-@deftypefnx {MGL command} {} zrange @code{v1 v2}
-@deftypefnx {MGL command} {} crange @code{v1 v2}
+@deftypefn {Команда MGL} {} xrange @code{v1 v2}
+@deftypefnx {Команда MGL} {} yrange @code{v1 v2}
+@deftypefnx {Команда MGL} {} zrange @code{v1 v2}
+@deftypefnx {Команда MGL} {} crange @code{v1 v2}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{float} v1, @code{float} v2)
 @deftypefnx {Функция С} @code{void} mgl_set_range_val (@code{HMGL} gr, @code{char} dir, @code{float} v1, @code{float} v2)
@@ -476,10 +476,10 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает диапазон изменения @samp{x}-,@samp{y}-,@samp{z}-,@samp{c}-координат. См. также @ref{ranges}.
 @end deftypefn
 
-@deftypefn {MGL command} {} xrange dat [@code{add=off}]
-@deftypefnx {MGL command} {} yrange dat [@code{add=off}]
-@deftypefnx {MGL command} {} zrange dat [@code{add=off}]
-@deftypefnx {MGL command} {} crange dat [@code{add=off}]
+@deftypefn {Команда MGL} {} xrange dat [@code{add=off}]
+@deftypefnx {Команда MGL} {} yrange dat [@code{add=off}]
+@deftypefnx {Команда MGL} {} zrange dat [@code{add=off}]
+@deftypefnx {Команда MGL} {} crange dat [@code{add=off}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{const mglData &}dat, @code{bool} add=@code{false})
 @deftypefnx {Функция С} @code{void} mgl_set_range_dat (@code{HMGL} gr, @code{char} dir, @code{const HCDT} a, @code{int} add)
@@ -488,7 +488,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{ranges}
-@deftypefn {MGL command} {} ranges @code{x1 x2 y1 y2 [z1=0 z2=0]}
+@deftypefn {Команда MGL} {} ranges @code{x1 x2 y1 y2 [z1=0 z2=0]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{float} x1, @code{float} x2, @code{float} y1, @code{float} y2, @code{float} z1=@code{0}, @code{float} z2=@code{0})
@@ -506,7 +506,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end ifclear
 
 @anchor{origin}
-@deftypefn {MGL command} {} origin @code{x0 y0 [z0=nan]}
+@deftypefn {Команда MGL} {} origin @code{x0 y0 [z0=nan]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetOrigin (@code{mglPoint} p0)
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetOrigin (@code{float} x0, @code{float} y0, @code{float} z0=@code{NAN})
@@ -526,7 +526,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @cindex Ternary
 @end ifclear
 
-@deftypefn {MGL command} {} axis 'fx' 'fy' ['fz'='' 'fa'='']
+@deftypefn {Команда MGL} {} axis 'fx' 'fy' ['fz'='' 'fa'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetFunc (@code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ=@code{""}, @code{const char *}EqA=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_set_func (@code{HMGL} gr, @code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ, @code{const char *}EqA)
@@ -534,7 +534,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает формулы перехода к криволинейным координатам. Каждая строка является математическим выражением, зависящим от старых координат @samp{x}, @samp{y}, @samp{z} и @samp{a} или @samp{c} для цветовой шкалы. Например, для цилиндрических координат будет @code{SetFunc("x*cos(y)", "x*sin(y)", "z");}. Для удаления формул соответствующий параметр должен быть пустым или @code{NULL}. Использование формул преобразования слегка замедляет программу. Параметр @var{EqA} задает аналогичную формулу для цветовой шкалы. @xref{Textual formulas}.
 @end deftypefn
 
-@deftypefn {MGL command} {} axis @code{how}
+@deftypefn {Команда MGL} {} axis @code{how}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCoor (@code{int} how)
 @deftypefnx {Функция С} @code{void} mgl_set_coor (@code{HMGL} gr, @code{int} how)
@@ -543,7 +543,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{ternary}
-@deftypefn {MGL command} {} ternary @code{val}
+@deftypefn {Команда MGL} {} ternary @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Ternary (@code{int} tern)
 @deftypefnx {Функция С} @code{void} mgl_set_ternary (@code{HMGL} gr, @code{int} tern)
@@ -574,7 +574,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end ifclear
 
 @anchor{adjust}
-@deftypefn {MGL command} {} adjust ['dir'='xyzc']
+@deftypefn {Команда MGL} {} adjust ['dir'='xyzc']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Adjust (@code{const char *}dir=@code{"xyzc"})
 @deftypefnx {Функция С} @code{void} mgl_adjust_ticks (@code{HMGL} gr, @code{const char *}dir)
@@ -586,10 +586,10 @@ Setsize: размер(ы) равны нулю или отрицательны
 @anchor{ytick}
 @anchor{ztick}
 @anchor{ctick}
-@deftypefn {MGL command} {} xtick @code{val [sub=0 org=nan]}
-@deftypefnx {MGL command} {} ytick @code{val [sub=0 org=nan]}
-@deftypefnx {MGL command} {} ztick @code{val [sub=0 org=nan]}
-@deftypefnx {MGL command} {} ctick @code{val [sub=0 org=nan]}
+@deftypefn {Команда MGL} {} xtick @code{val [sub=0 org=nan]}
+@deftypefnx {Команда MGL} {} ytick @code{val [sub=0 org=nan]}
+@deftypefnx {Команда MGL} {} ztick @code{val [sub=0 org=nan]}
+@deftypefnx {Команда MGL} {} ctick @code{val [sub=0 org=nan]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{float} d=@code{0}, @code{int} ns=@code{0}, @code{float} org=@code{NAN})
 @deftypefnx {Функция С} @code{void} mgl_set_ticks_dir (@code{HMGL} gr, @code{char} dir, @code{float} d, @code{int} ns, @code{float} org)
@@ -598,9 +598,9 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает шаг меток осей @var{d}, число подметок @var{ns} и начальное положение меток @var{org} для оси вдоль направления @var{dir} (используйте 'c' для меток colorbar). Переменная @var{d} задает шаг меток (если положительна) или их число на оси (если отрицательна). Нулевое значение задает автоматическую расстановку меток. Если @var{org}=@code{NAN}, то используется значение из переменной @var{Org}.
 @end deftypefn
 
-@deftypefn {MGL command} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
-@deftypefnx {MGL command} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
-@deftypefnx {MGL command} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
+@deftypefn {Команда MGL} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
+@deftypefnx {Команда MGL} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
+@deftypefnx {Команда MGL} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const char *}lbl, @code{bool} add=@code{false})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
@@ -614,10 +614,10 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает явное положение @var{val} и подписи @var{lbl} для меток вдоль оси @var{dir}. Если массив @var{val} не указан, то используются значения равно распределённые в интервале [@var{Min}.x, @var{Max}.x]. Метки разделяются символом @samp{\n}. Используйте @code{SetTicks()} для восстановления автоматических меток.
 @end deftypefn
 
-@deftypefn {MGL command} {} xtick 'templ'
-@deftypefnx {MGL command} {} ytick 'templ'
-@deftypefnx {MGL command} {} ztick 'templ'
-@deftypefnx {MGL command} {} ctick 'templ'
+@deftypefn {Команда MGL} {} xtick 'templ'
+@deftypefnx {Команда MGL} {} ytick 'templ'
+@deftypefnx {Команда MGL} {} ztick 'templ'
+@deftypefnx {Команда MGL} {} ctick 'templ'
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const char *}templ)
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const wchar_t *}templ)
@@ -627,7 +627,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает шаблон @var{templ} для меток вдоль x-,y-,z-оси или colorbar. Шаблон может содержать и символы TeX. Если @var{templ}=@code{""}, то используется шаблон по умолчанию (в простейшем случае @samp{%.2g}). Установка шаблона выключает автоматическое улучшение вида меток.
 @end deftypefn
 
-@deftypefn {MGL command} {} ticktime 'dir' [@code{dv} 'tmpl']
+@deftypefn {Команда MGL} {} ticktime 'dir' [@code{dv} 'tmpl']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksTime (@code{char} dir, @code{float} val, @code{const char *}templ)
 @deftypefnx {Функция С} @code{void} mgl_set_ticks_time (@code{HMGL} gr, @code{float} val, @code{const char *}templ)
@@ -635,7 +635,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает метки времени с шагом @var{val} и шаблоном @var{templ} для меток вдоль x-,y-,z-оси или colorbar. Шаблон может содержать и символы TeX. Формат шаблона @var{templ} такой же как @url{http://www.manpagez.com/man/3/strftime/}. Наиболее употребительные варианты: @samp{%X} для национального представления времени, @samp{%x} для национального представления даты, @samp{%Y} для года с цифрами столетия. Если @var{val}=0 и/или @var{templ}="", то используется автоматическая расстановка меток и/или выбор шаблона.
 @end deftypefn
 
-@deftypefn {MGL command} {} tuneticks @code{val} [@code{pos=1.15}]
+@deftypefn {Команда MGL} {} tuneticks @code{val} [@code{pos=1.15}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTuneTicks (@code{int} tune, @code{float} pos=@code{1.15})
 @deftypefnx {Функция С} @code{void} mgl_tune_ticks (@code{HMGL} gr, @code{int} tune, @code{float} pos)
@@ -657,7 +657,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 
 
 @anchor{ticklen}
-@deftypefn {MGL command} {} ticklen @code{val} [@code{stt=1}]
+@deftypefn {Команда MGL} {} ticklen @code{val} [@code{stt=1}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickLen (@code{float} val, @code{float} stt=@code{1})
 @deftypefnx {Функция С} @code{void} mgl_set_tick_len (@code{HMGL} gr, @code{float} val, @code{float} stt)
@@ -665,7 +665,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Задает относительную длину меток осей координат. Значение по умолчанию @code{0.1}. Параметр @var{stt}>0 задает относительную длину подметок, которые в @code{sqrt(1+stt)} раз меньше.
 @end deftypefn
 
-@deftypefn {MGL command} {} axisstl 'stl' ['tck'='' 'sub'='']
+@deftypefn {Команда MGL} {} axisstl 'stl' ['tck'='' 'sub'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAxisStl (@code{const char *}stl=@code{"k"}, @code{const char *}tck=@code{0}, @code{const char *}sub=@code{0})
 @deftypefnx {Функция С} @code{void} mgl_set_axis_stl (@code{HMGL} gr, @code{const char *}stl, @code{const char *}tck, @code{const char *}sub)
@@ -693,7 +693,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Эти функции контролируют где и как график будет расположен. Существует определенный порядок вызова этих функций для лучшего вида графика. Вначале должны вызываться функции SubPlot() или InPlot() для указания местоположения вывода. После них -- функции вращения Rotate() и сжатия Aspect(). И наконец любые другие функции для рисования графика. Вместо вращения графика можно вызвать функцию ColumnPlot() для расположения графиков в столбец одного над другим без зазора между осями. @sref{Subplots}
 
 @anchor{subplot}
-@deftypefn {MGL command} {} subplot @code{nx ny m ['stl'='<>_^' dx=0 dy=0]}
+@deftypefn {Команда MGL} {} subplot @code{nx ny m ['stl'='<>_^' dx=0 dy=0]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SubPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl=@code{"<>_^"}, @code{float} dx=@code{0}, @code{float} dy=@code{0})
 @deftypefnx {Функция С} @code{void} mgl_subplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl)
@@ -703,7 +703,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{multiplot}
-@deftypefn {MGL command} {} multiplot @code{nx ny m dx dy} ['style'='<>_^']
+@deftypefn {Команда MGL} {} multiplot @code{nx ny m dx dy} ['style'='<>_^']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} MultiPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl=@code{"<>_^"})
 @deftypefnx {Функция С} @code{void} mgl_multiplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl)
@@ -712,7 +712,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{inplot}
-@deftypefn {MGL command} {} inplot @code{x1 x2 y1 y2 [rel=off]}
+@deftypefn {Команда MGL} {} inplot @code{x1 x2 y1 y2 [rel=off]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} InPlot (@code{float} x1, @code{float} x2, @code{float} y1, @code{float} y2, @code{bool} rel=@code{false})
 @deftypefnx {Функция С} @code{void} mgl_inplot (@code{HMGL} gr, @code{float} x1, @code{float} x2, @code{float} y1, @code{float} y2)
@@ -722,7 +722,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{columnplot}
-@deftypefn {MGL command} {} columnplot @code{num ind [d=0]}
+@deftypefn {Команда MGL} {} columnplot @code{num ind [d=0]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} ColumnPlot (@code{int} num, @code{int} ind, @code{float} d=@code{0})
 @deftypefnx {Функция С} @code{void} mgl_columnplot (@code{HMGL} gr, @code{int} num, @code{int} ind)
@@ -732,7 +732,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{gridplot}
-@deftypefn {MGL command} {} gridplot @code{nx ny ind [d=0]}
+@deftypefn {Команда MGL} {} gridplot @code{nx ny ind [d=0]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} GridPlot (@code{int} nx, @code{int} ny, @code{int} ind, @code{float} d=@code{0})
 @deftypefnx {Функция С} @code{void} mgl_gridplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} ind)
@@ -742,7 +742,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{stickplot}
-@deftypefn {MGL command} {} stickplot @code{num ind tet phi}
+@deftypefn {Команда MGL} {} stickplot @code{num ind tet phi}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} StickPlot (@code{int} num, @code{int} ind, @code{float} tet, @code{float} phi)
 @deftypefnx {Функция С} @code{void} mgl_stickplot (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{float} tet, @code{float} phi)
@@ -752,7 +752,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 
 
 @anchor{title}
-@deftypefn {MGL command} {} title 'title' ['stl'='' @code{size=-2}]
+@deftypefn {Команда MGL} {} title 'title' ['stl'='' @code{size=-2}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Title (@code{const char *}txt, @code{const char *}stl=@code{""}, @code{float} size=@code{-2})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Title (@code{const wchar_t *}txt, @code{const char *}stl=@code{""}, @code{float} size=@code{-2})
@@ -763,7 +763,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{rotate}
-@deftypefn {MGL command} {} rotate @code{tetz tetx [tety=0]}
+@deftypefn {Команда MGL} {} rotate @code{tetz tetx [tety=0]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Rotate (@code{float} TetX, @code{float} TetZ, @code{float} TetY=@code{0})
 @deftypefnx {Функция С} @code{void} mgl_rotate (@code{HMGL} gr, @code{float} TetX, @code{float} TetZ, @code{float} TetY)
@@ -771,7 +771,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Вращает систему координат относительно осей @{x, z, y@} последовательно на углы @var{TetX}, @var{TetZ}, @var{TetY}.
 @end deftypefn
 
-@deftypefn {MGL command} {} rotate @code{tet x y z}
+@deftypefn {Команда MGL} {} rotate @code{tet x y z}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} RotateN (@code{float} Tet, @code{float} x, @code{float} y, @code{float} z)
 @deftypefnx {Функция С} @code{void} mgl_rotate_vector (@code{HMGL} gr, @code{float Tet}, @code{float x}, @code{float y}, @code{float z})
@@ -780,7 +780,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{aspect}
-@deftypefn {MGL command} {} aspect @code{ax ay [az=1]}
+@deftypefn {Команда MGL} {} aspect @code{ax ay [az=1]}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Aspect (@code{float} Ax, @code{float} Ay, @code{float} Az=@code{1})
 @deftypefnx {Функция С} @code{void} mgl_aspect (@code{HMGL} gr, @code{float} Ax, @code{float} Ay, @code{float} Az)
@@ -789,7 +789,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{perspective}
-@deftypefn {MGL command} {} perspective @code{val}
+@deftypefn {Команда MGL} {} perspective @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Perspective (@code{float} a)
 @deftypefnx {Функция С} @code{void} mgl_perspective (@code{HMGL} gr, @code{float} a)
@@ -837,7 +837,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Функции в этой группе сохраняют или дают доступ к полученному рисунку. Поэтом обычно они должны вызываться в конце рисования.
 
 @anchor{setsize}
-@deftypefn {MGL command} {} setsize @code{w h}
+@deftypefn {Команда MGL} {} setsize @code{w h}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height)
 @deftypefnx {Функция С} @code{void} mgl_set_size (@code{HMGL} gr, @code{int} width, @code{int} height)
@@ -846,7 +846,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 @anchor{quality}
-@deftypefn {MGL command} {} quality @code{val}
+@deftypefn {Команда MGL} {} quality @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetQuality (@code{int} val=@code{MGL_DRAW_NORM})
 @deftypefnx {Функция С} @code{void} mgl_set_quality (@code{HMGL} gr, @code{int} val)
@@ -897,7 +897,7 @@ Setsize: размер(ы) равны нулю или отрицательны
 Эти функции экспортируют текущую картинку (кадр) в файл. Имя файла @var{fname} должно иметь соответствующее расширение. Параметр @var{descr} дает краткое описание картинки. Пока прозрачность поддерживается только для форматов PNG, SVG, OBJ и IDTF.
 
 @anchor{write}
-@deftypefn {MGL command} {} write ['fname'='']
+@deftypefn {Команда MGL} {} write ['fname'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} WriteFrame (@code{const char *}fname=@code{""}, @code{const char *}descr=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_write_frame (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
@@ -991,13 +991,13 @@ Setsize: размер(ы) равны нулю или отрицательны
 @end deftypefn
 
 
-@deftypefn {Method on @code{mglGraph}} @code{void} ExportMGLD (@code{const char *}fname, @code{const char *}descr=@code{""})
-@deftypefnx {C function} @code{void} mgl_export_mgld (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
+@deftypefn {Метод класса @code{mglGraph}} @code{void} ExportMGLD (@code{const char *}fname, @code{const char *}descr=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_export_mgld (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
 Экспортирует точки и примитивы в файл MGLD формата. В дальнейшем этот файл можно загрузить и просмотреть с помощью @code{mglview}. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
 @end deftypefn
 
-@deftypefn {Method on @code{mglGraph}} @code{void} ImportMGLD (@code{const char *}fname, @code{bool} add=@code{false})
-@deftypefnx {C function} @code{void} mgl_import_mgld (@code{HMGL} gr, @code{const char *}fname, @code{int} add)
+@deftypefn {Метод класса @code{mglGraph}} @code{void} ImportMGLD (@code{const char *}fname, @code{bool} add=@code{false})
+@deftypefnx {Функция С} @code{void} mgl_import_mgld (@code{HMGL} gr, @code{const char *}fname, @code{int} add)
 Импортирует точки и примитивы из файла в формате MGLD. Параметры функции следующие: @var{fname} -- имя файла, @var{add} -- флаг добавления или замены существующих точек и примитивов.
 @end deftypefn
 
@@ -1060,10 +1060,10 @@ Setsize: размер(ы) равны нулю или отрицательны
 @ifclear UDAV
 Эти функции возвращают созданный растровый рисунок, его ширину и высоту. В дальнейшем его можно использовать в любой графической библиотеке (см. также, @ref{Widget classes}) или сохранить в файл (см. также, @ref{Export to file}).
 
-@deftypefn {Method on @code{mglGraph}} @code{const unsigned char *} GetRGB ()
-@deftypefnx {Method on @code{mglGraph}} @code{void} GetRGB (@code{char *}buf, @code{int} size)
-@deftypefnx {Method on @code{mglGraph}} @code{void} GetBGRN (@code{char *}buf, @code{int} size)
-@deftypefnx {C function} @code{const unsigned char *} mgl_get_rgb (@code{HMGL} gr)
+@deftypefn {Метод класса @code{mglGraph}} @code{const unsigned char *} GetRGB ()
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetRGB (@code{char *}buf, @code{int} size)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetBGRN (@code{char *}buf, @code{int} size)
+@deftypefnx {Функция С} @code{const unsigned char *} mgl_get_rgb (@code{HMGL} gr)
 Возвращает растровое изображение в формате RGB для текущего кадра. Формат каждого элемента (пикселя): @{red, green, blue@}. Число элементов Width*Height. Положение элемента @{i,j@} есть [3*i + 3*Width*j] (или [4*i + 4*Width*j] для @code{GetBGRN()}). В Python вы должны предоставить буфер @var{buf} достаточного размера @var{size}, т.е. код должен выглядеть следующим образом
 @verbatim
 from mathgl import *
@@ -1074,9 +1074,9 @@ gr.GetBGRN(bits, len(bits));
 @end verbatim
 @end deftypefn
 
-@deftypefn {Method on @code{mglGraph}} @code{const unsigned char *} GetRGBA ()
-@deftypefnx {Method on @code{mglGraph}} @code{void} GetRGBA (@code{char *}buf, @code{int} size)
-@deftypefnx {C function} @code{const unsigned char *} mgl_get_rgba (@code{HMGL} gr)
+@deftypefn {Метод класса @code{mglGraph}} @code{const unsigned char *} GetRGBA ()
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetRGBA (@code{char *}buf, @code{int} size)
+@deftypefnx {Функция С} @code{const unsigned char *} mgl_get_rgba (@code{HMGL} gr)
 Возвращает растровое изображение в формате RGBA для текущего кадра. Формат каждого элемента (пикселя): @{red, green, blue, alpha@}. Число элементов Width*Height. Положение элемента @{i,j@} есть [4*i + 4*Width*j].
 @end deftypefn
 
@@ -1113,8 +1113,8 @@ gr.GetBGRN(bits, len(bits));
 Возвращает числовой идентификатор верхнего "подграфика" в точке @{xs, ys@} рисунка.
 @end deftypefn
 
-@deftypefn {Method on @code{mglGraph}} @code{void} Highlight (@code{int} id)
-@deftypefnx {C function} @code{void} mgl_highlight (@code{HMGL} gr, @code{int} id)
+@deftypefn {Метод класса @code{mglGraph}} @code{void} Highlight (@code{int} id)
+@deftypefnx {Функция С} @code{void} mgl_highlight (@code{HMGL} gr, @code{int} id)
 Выделяет объект с заданным @var{id}.
 @end deftypefn
 
@@ -1133,7 +1133,7 @@ gr.GetBGRN(bits, len(bits));
 
 Многие функции MathGL используют несколько потоков для ускорения работы (если MathGL была собрана с поддержкой pthread). При этом можно настраивать число используемых потоков.
 
-@deftypefn {C function} @code{int} mgl_set_num_thr (@code{int} n)
+@deftypefn {Функция С} @code{int} mgl_set_num_thr (@code{int} n)
 Задает число потоков, которое будет использовано в MathGL. При @var{n}<1 число потоков задается как максимальное число процессоров (ядер) в системе. При @var{n}=1 не используется распараллеливание.
 @end deftypefn
 
@@ -1180,7 +1180,7 @@ gr.GetBGRN(bits, len(bits));
 Эти функции рисуют рисуют простые объекты типа линий, точек, сфер, капель, конусов, и т.д.
 
 @anchor{clf}
-@deftypefn {MGL command} {} clf
+@deftypefn {Команда MGL} {} clf
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf ()
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{float} r, @code{float} g, @code{float} b)
@@ -1191,8 +1191,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{ball}
-@deftypefn {MGL command} {} ball @code{x y} ['col'='r.']
-@deftypefnx {MGL command} {} ball @code{x y z} ['col'='r.']
+@deftypefn {Команда MGL} {} ball @code{x y} ['col'='r.']
+@deftypefnx {Команда MGL} {} ball @code{x y z} ['col'='r.']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Ball (@code{mglPoint} p, @code{char} col=@code{'r'})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{mglPoint} p, @code{const char *}mark)
@@ -1203,15 +1203,15 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @ifclear UDAV
-@deftypefn {Method on @code{mglGraph}} @code{void} Error (@code{mglPoint} p, @code{mglPoint} e, @code{char} *stl=@code{""})
-@deftypefnx {C function} @code{void} mgl_error_box (@code{HMGL} gr, @code{float} px, @code{float} py, @code{float} pz, @code{float} ex, @code{float} ey, @code{float} ez, @code{char *}stl)
+@deftypefn {Метод класса @code{mglGraph}} @code{void} Error (@code{mglPoint} p, @code{mglPoint} e, @code{char} *stl=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_error_box (@code{HMGL} gr, @code{float} px, @code{float} py, @code{float} pz, @code{float} ex, @code{float} ey, @code{float} ez, @code{char *}stl)
 Рисует 3d error box в точке @var{p} размером @var{e} и стилем @var{stl}.
 @end deftypefn
 @end ifclear
 
 @anchor{line}
-@deftypefn {MGL command} {} line @code{x1 y1 x2 y2} ['stl'='']
-@deftypefnx {MGL command} {} line @code{x1 y1 z1 x2 y2 z2} ['stl'='']
+@deftypefn {Команда MGL} {} line @code{x1 y1 x2 y2} ['stl'='']
+@deftypefnx {Команда MGL} {} line @code{x1 y1 z1 x2 y2 z2} ['stl'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Line (@code{mglPoint} p1, @code{mglPoint} p2, @code{char *}stl=@code{"B"}, @code{int}num=@code{2})
 @deftypefnx {Функция С} @code{void} mgl_line (@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} x2, @code{float} y2, @code{float} z2, @code{char *}stl, @code{int}num)
@@ -1220,8 +1220,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{curve}
-@deftypefn {MGL command} {} curve @code{x1 y1 dx1 dy1 x2 y2 dx2 dy2} ['stl'='']
-@deftypefnx {MGL command} {} curve @code{x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2} ['stl'='']
+@deftypefn {Команда MGL} {} curve @code{x1 y1 dx1 dy1 x2 y2 dx2 dy2} ['stl'='']
+@deftypefnx {Команда MGL} {} curve @code{x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2} ['stl'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Curve (@code{mglPoint} p1, @code{mglPoint} d1, @code{mglPoint} p2, @code{mglPoint} d2, @code{const char *}stl=@code{"B"}, @code{int} num=@code{100})
 @deftypefnx {Функция С} @code{void} mgl_curve (@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} dx1, @code{float} dy1, @code{float} dz1, @code{float} x2, @code{float} y2, @code{float} z2, @code{float} dx2, @code{float} dy2, @code{float} dz2, @code{const char *}stl, @code{int} num)
@@ -1239,9 +1239,9 @@ gr.GetBGRN(bits, len(bits));
 @anchor{facex}
 @anchor{facey}
 @anchor{facez}
-@deftypefn {MGL command} {} facex @code{x0 y0 z0 wy wz} ['stl'='' @code{d1=0 d2=0}]
-@deftypefnx {MGL command} {} facey @code{x0 y0 z0 wx wz} ['stl'='' @code{d1=0 d2=0}]
-@deftypefnx {MGL command} {} facez @code{x0 y0 z0 wx wy} ['stl'='' @code{d1=0 d2=0}]
+@deftypefn {Команда MGL} {} facex @code{x0 y0 z0 wy wz} ['stl'='' @code{d1=0 d2=0}]
+@deftypefnx {Команда MGL} {} facey @code{x0 y0 z0 wx wz} ['stl'='' @code{d1=0 d2=0}]
+@deftypefnx {Команда MGL} {} facez @code{x0 y0 z0 wx wy} ['stl'='' @code{d1=0 d2=0}]
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceX (@code{float} x0, @code{float} y0, @code{float} z0, @code{float} wy, @code{float} wz, @code{const char *}stl=@code{"w"}, @code{float} d1=@code{0}, @code{float} d2=@code{0})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceY (@code{float} x0, @code{float} y0, @code{float} z0, @code{float} wx, @code{float} wz, @code{const char *}stl=@code{"w"}, @code{float} d1=@code{0}, @code{float} d2=@code{0})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceZ (@code{float} x0, @code{float} y0, @code{float} z0, @code{float} wx, @code{float} wy, @code{const char *}stl=@code{"w"}, @code{float} d1=@code{0}, @code{float} d2=@code{0})
@@ -1252,8 +1252,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{sphere}
-@deftypefn {MGL command} {} sphere @code{x0 y0 r} ['col'='r']
-@deftypefnx {MGL command} {} sphere @code{x0 y0 z0 r} ['col'='r']
+@deftypefn {Команда MGL} {} sphere @code{x0 y0 r} ['col'='r']
+@deftypefnx {Команда MGL} {} sphere @code{x0 y0 z0 r} ['col'='r']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Sphere (@code{mglPoint} p, @code{float} r, @code{const char *}stl=@code{"r"})
 @deftypefnx {Функция С} @code{void} mgl_sphere (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{float} r, @code{const char *}stl)
@@ -1262,17 +1262,17 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{drop}
-@deftypefn {MGL command} {} drop @code{x0 y0 dx dy r} ['col'='r' @code{sh=1 asp=1}]
-@deftypefnx {MGL command} {} drop @code{x0 y0 z0 dx dy dz r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefn {Команда MGL} {} drop @code{x0 y0 dx dy r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefnx {Команда MGL} {} drop @code{x0 y0 z0 dx dy dz r} ['col'='r' @code{sh=1 asp=1}]
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Drop (@code{mglPoint} p, @code{mglPoint} d, @code{float} r, @code{const char *}col=@code{"r"}, @code{float} shift=@code{1}, @code{float} ap=@code{1})
-@deftypefnx {C function} @code{void} mgl_drop (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{float} dx, @code{float} dy, @code{float} dz, @code{float} r, @code{const char *}col, @code{float} shift, @code{float} ap)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Drop (@code{mglPoint} p, @code{mglPoint} d, @code{float} r, @code{const char *}col=@code{"r"}, @code{float} shift=@code{1}, @code{float} ap=@code{1})
+@deftypefnx {Функция С} @code{void} mgl_drop (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{float} dx, @code{float} dy, @code{float} dz, @code{float} r, @code{const char *}col, @code{float} shift, @code{float} ap)
 @end ifclear
 Рисует каплю радиуса @var{r} в точке @var{p} вытянутую вдоль направления @var{d} цветом @var{col}. Параметр @var{shift} определяет степень вытянутости: @samp{0} -- сфера, @samp{1} -- классическая капля. Параметр @var{ap} определяет относительную ширину капли (аналог "эллиптичности" для сферы). @sref{Drops sample}
 @end deftypefn
 
 @anchor{cone}
-@deftypefn {MGL command} {} cone @code{x1 y1 z1 x2 y2 z2 r1} [@code{r2=-1} 'stl'='' @code{edge=off}]
+@deftypefn {Команда MGL} {} cone @code{x1 y1 z1 x2 y2 z2 r1} [@code{r2=-1} 'stl'='' @code{edge=off}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Cone (@code{mglPoint} p1, @code{mglPoint} p2, @code{float} r1, @code{float} r2=@code{-1}, @code{const char *}stl=@code{"B"}, @code{bool} edge=@code{false})
 @deftypefnx {Функция С} @code{void} mgl_cone (@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} x2, @code{float} y2, @code{float} z2, @code{float} r1, @code{float} r2, @code{const char *}stl, @code{int} draw_edge)
@@ -1281,8 +1281,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{circle}
-@deftypefn {MGL command} {} circle @code{x0 y0 r} ['col'='r']
-@deftypefnx {MGL command} {} circle @code{x0 y0 z0 r} ['col'='r']
+@deftypefn {Команда MGL} {} circle @code{x0 y0 r} ['col'='r']
+@deftypefnx {Команда MGL} {} circle @code{x0 y0 z0 r} ['col'='r']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Circle (@code{mglPoint} p, @code{float} r, @code{const char *}stl=@code{"r"})
 @end ifclear
@@ -1290,8 +1290,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{ellipse}
-@deftypefn {MGL command} {} ellipse @code{x1 y1 x2 y2 r} ['col'='r' @code{sh=1 asp=1}]
-@deftypefnx {MGL command} {} ellipse @code{x1 y1 z1 x2 y2 z2 r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefn {Команда MGL} {} ellipse @code{x1 y1 x2 y2 r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefnx {Команда MGL} {} ellipse @code{x1 y1 z1 x2 y2 z2 r} ['col'='r' @code{sh=1 asp=1}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Ellipse (@code{mglPoint} p1, @code{mglPoint} p2, @code{float} r, @code{const char *}col=@code{"r"})
 @deftypefnx {Функция С} @code{void} mgl_ellipse(@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} x2, @code{float} y2, @code{float} z2, @code{float} r, @code{const char *}col)
@@ -1300,8 +1300,8 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{rhomb}
-@deftypefn {MGL command} {} rhomb @code{x1 y1 x2 y2 r} ['col'='r' @code{sh=1 asp=1}]
-@deftypefnx {MGL command} {} rhomb @code{x1 y1 z1 x2 y2 z2 r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefn {Команда MGL} {} rhomb @code{x1 y1 x2 y2 r} ['col'='r' @code{sh=1 asp=1}]
+@deftypefnx {Команда MGL} {} rhomb @code{x1 y1 z1 x2 y2 z2 r} ['col'='r' @code{sh=1 asp=1}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Rhomb (@code{mglPoint} p1, @code{mglPoint} p2, @code{float} r, @code{const char *}col=@code{"r"})
 @deftypefnx {Функция С} @code{void} mgl_rhomb(@code{HMGL} gr, @code{float} x1, @code{float} y1, @code{float} z1, @code{float} x2, @code{float} y2, @code{float} z2, @code{float} r, @code{const char *}col)
@@ -1329,8 +1329,8 @@ gr.GetBGRN(bits, len(bits));
 @sref{Text features}
 
 @anchor{text}
-@deftypefn {MGL command} {} text @code{x y} 'text' ['fnt'='' @code{size=-1}]
-@deftypefnx {MGL command} {} text @code{x y z} 'text' ['fnt'='' @code{size=-1}]
+@deftypefn {Команда MGL} {} text @code{x y} 'text' ['fnt'='' @code{size=-1}]
+@deftypefnx {Команда MGL} {} text @code{x y z} 'text' ['fnt'='' @code{size=-1}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{float} size=@code{-1})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{float} size=@code{-1})
@@ -1340,8 +1340,8 @@ gr.GetBGRN(bits, len(bits));
 Выводит строку @var{text} от точки @var{p} шрифтом определяемым строкой @var{fnt}.
 @end deftypefn
 
-@deftypefn {MGL command} {} text @code{x y dx dy} 'text' ['fnt'=':L' @code{size=-1}]
-@deftypefnx {MGL command} {} text @code{x y z dx dy dz} 'text' ['fnt'=':L' @code{size=-1}]
+@deftypefn {Команда MGL} {} text @code{x y dx dy} 'text' ['fnt'=':L' @code{size=-1}]
+@deftypefnx {Команда MGL} {} text @code{x y z dx dy dz} 'text' ['fnt'=':L' @code{size=-1}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{mglPoint} d, @code{const char *}text, @code{const char *}fnt=@code{':L'}, @code{float} size=@code{-1})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{mglPoint} d, @code{const wchar_t *}text, @code{const char *}fnt=@code{':L'}, @code{float} size=@code{-1})
@@ -1352,14 +1352,14 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{fgets}
-@deftypefn {MGL command} {} fgets @code{x y} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
-@deftypefnx {MGL command} {} fgets @code{x y z} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
+@deftypefn {Команда MGL} {} fgets @code{x y} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
+@deftypefnx {Команда MGL} {} fgets @code{x y z} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
 Выводит @var{n}-ую строку файла @var{fname} от точки @{@var{x},@var{y},@var{z}@} шрифтом @var{fnt} и размером @var{size}.
 @end deftypefn
 
-@deftypefn {MGL command} {} text ydat 'text' ['fnt'='']
-@deftypefnx {MGL command} {} text xdat ydat 'text' ['fnt'='' @code{size=-1 zval=nan}]
-@deftypefnx {MGL command} {} text xdat ydat zdat 'text' ['fnt'='' @code{size=-1}]
+@deftypefn {Команда MGL} {} text ydat 'text' ['fnt'='']
+@deftypefnx {Команда MGL} {} text xdat ydat 'text' ['fnt'='' @code{size=-1 zval=nan}]
+@deftypefnx {Команда MGL} {} text xdat ydat zdat 'text' ['fnt'='' @code{size=-1}]
 @ifclear UDAV
 @deftypefn {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglData &}y, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglData &}y, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
@@ -1389,16 +1389,16 @@ gr.GetBGRN(bits, len(bits));
 Эти функции рисуют объекты для "измерения" типа осей координат, цветовой таблицы (colorbar), сетку по осям, обрамляющий параллелепипед и подписи по осям координат. См. также см. @ref{Axis settings}.
 
 @anchor{axis}
-@deftypefn {MGL command} {} axis ['dir'='xyz' 'stl'='']
+@deftypefn {Команда MGL} {} axis ['dir'='xyz' 'stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""})
-@deftypefnx {C function} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl)
 @end ifclear
 Рисует оси координат и метки на них (см. @ref{Axis settings}) в направлениях @samp{xyz}, указанных строкой @var{dir}. Если строка содержит символ @samp{_}, то подписи меток отображаться не будут. Если строка содержит символ @samp{AKDTVISO}, то будет нарисована соответствующая стрелка на конце оси. Стиль меток и оси(ей) задается строкой @var{stl}. @sref{Axis and ticks}
 @end deftypefn
 
 @anchor{colorbar}
-@deftypefn {MGL command} {} colorbar ['sch'='']
+@deftypefn {Команда MGL} {} colorbar ['sch'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_colorbar (@code{HMGL} gr, @code{const char *}sch)
@@ -1406,7 +1406,7 @@ gr.GetBGRN(bits, len(bits));
 Рисует полосу соответствия цвета и числовых значений (colorbar) для цветовой схемы @var{sch} (используется текущая для @code{sch=""}) с краю от графика. Если строка @var{sch} содержит @samp{<>^_}, то положение выбирается: @samp{>} -- справа, @samp{<} -- слева, @samp{^} -- сверху, @samp{_} -- снизу. Если строка содержит @samp{A}, то используются абсолютные координаты (относительно рисунка). @sref{Colorbars}
 @end deftypefn
 
-@deftypefn {MGL command} {} colorbar vdat ['sch'='']
+@deftypefn {Команда MGL} {} colorbar vdat ['sch'='']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const mglData &}v, @code{const char *}sch=@code{""})
 @deftypefnx {Функция С} @code{void} mgl_colorbar_val (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch)
@@ -1414,24 +1414,24 @@ gr.GetBGRN(bits, len(bits));
 Аналогично предыдущему, но для цветовой схемы без сглаживания с заданными значениями @var{v}. @sref{ContD sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} colorbar 'sch' @code{x y [w=1 h=1]}
+@deftypefn {Команда MGL} {} colorbar 'sch' @code{x y [w=1 h=1]}
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch, @code{float} x, @code{float} y, @code{float} w=@code{1}, @code{float} h=@code{1})
-@deftypefnx {C function} @code{void} mgl_colorbar_ext (@code{HMGL} gr, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w, @code{float} h)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch, @code{float} x, @code{float} y, @code{float} w=@code{1}, @code{float} h=@code{1})
+@deftypefnx {Функция С} @code{void} mgl_colorbar_ext (@code{HMGL} gr, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w, @code{float} h)
 @end ifclear
 Аналогично первому, но в произвольном месте графика @{@var{x}, @var{y}@} (полагаются в диапазоне [0,1]). Параметры @var{w}, @var{h} задают относительную ширину и высоту colorbar.
 @end deftypefn
 
-@deftypefn {MGL command} {} colorbar vdat 'sch' @code{x y [w=1 h=1]}
+@deftypefn {Команда MGL} {} colorbar vdat 'sch' @code{x y [w=1 h=1]}
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const mglData &}v, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w=@code{1}, @code{float} h=@code{1})
-@deftypefnx {C function} @code{void} mgl_colorbar_val_ext (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w, @code{float} h)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const mglData &}v, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w=@code{1}, @code{float} h=@code{1})
+@deftypefnx {Функция С} @code{void} mgl_colorbar_val_ext (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch, @code{float} x, @code{float} y, @code{float} w, @code{float} h)
 @end ifclear
 Аналогично предыдущему, но для цветовой схемы без сглаживания с заданными значениями @var{v}.
 @end deftypefn
 
 @anchor{grid}
-@deftypefn {MGL command} {} grid ['dir'='xyz' 'pen'='B']
+@deftypefn {Команда MGL} {} grid ['dir'='xyz' 'pen'='B']
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const char *}dir=@code{"xyz"}, @code{const char *}pen=@code{"B"})
 @deftypefnx {Функция С} @code{void} mgl_axis_grid (@code{HMGL} gr, @code{const char *}dir, @code{const char *}pen)
@@ -1440,7 +1440,7 @@ gr.GetBGRN(bits, len(bits));
 @end deftypefn
 
 @anchor{box}
-@deftypefn {MGL command} {} box ['stl'='k' @code{ticks=on}]
+@deftypefn {Команда MGL} {} box ['stl'='k' @code{ticks=on}]
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} Box (@code{const char *}col=@code{""}, @code{bool} ticks=@code{true})
 @deftypefnx {Функция С} @code{void} mgl_box (@code{HMGL} gr, @code{int} ticks)
@@ -1453,16 +1453,16 @@ gr.GetBGRN(bits, len(bits));
 @anchor{ylabel}
 @anchor{zlabel}
 @anchor{tlabel}
-@deftypefn {MGL command} {} xlabel 'text' [@code{pos=1 shift=0}]
-@deftypefnx {MGL command} {} ylabel 'text' [@code{pos=1 shift=0}]
-@deftypefnx {MGL command} {} zlabel 'text' [@code{pos=1 shift=0}]
-@deftypefnx {MGL command} {} tlabel 'text' [@code{pos=1 shift=0}]
+@deftypefn {Команда MGL} {} xlabel 'text' [@code{pos=1 shift=0}]
+@deftypefnx {Команда MGL} {} ylabel 'text' [@code{pos=1 shift=0}]
+@deftypefnx {Команда MGL} {} zlabel 'text' [@code{pos=1 shift=0}]
+@deftypefnx {Команда MGL} {} tlabel 'text' [@code{pos=1 shift=0}]
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const char *}text, @code{float} pos=@code{1}, @code{float} shift=@code{0})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const wchar_t *}text, @code{float} pos=@code{1}, @code{float} shift=@code{0})
-@deftypefnx {C function} @code{void} mgl_label (@code{HMGL} gr, @code{char} dir, @code{const char *}text)
-@deftypefnx {C function} @code{void} mgl_label_ext (@code{HMGL} gr, @code{char} dir, @code{const char *}text, @code{float} pos, @code{float} shift)
-@deftypefnx {C function} @code{void} mgl_labelw_ext (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}text, @code{float} pos, @code{float} shift)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const char *}text, @code{float} pos=@code{1}, @code{float} shift=@code{0})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const wchar_t *}text, @code{float} pos=@code{1}, @code{float} shift=@code{0})
+@deftypefnx {Функция С} @code{void} mgl_label (@code{HMGL} gr, @code{char} dir, @code{const char *}text)
+@deftypefnx {Функция С} @code{void} mgl_label_ext (@code{HMGL} gr, @code{char} dir, @code{const char *}text, @code{float} pos, @code{float} shift)
+@deftypefnx {Функция С} @code{void} mgl_labelw_ext (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}text, @code{float} pos, @code{float} shift)
 @end ifclear
 Выводит подпись @var{text} для оси @var{dir}=@samp{x},@samp{y},@samp{z},@samp{t} (где @samp{t} -- ``тернарная'' ось @math{t=1-x-y}). Параметр @var{pos} задает положение подписи: при @var{pos}=0 -- по центру оси, при @var{pos}>0 -- около максимальных значений, при @var{pos}<0 -- около минимальных значений. @xref{Text printing}.
 @end deftypefn
@@ -1479,44 +1479,44 @@ gr.GetBGRN(bits, len(bits));
 Эти функции обеспечивают рисование легенды графика (полезно для @ref{1D plotting}). Запись в легенде состоит из двух строк: одна для стиля линии и маркеров, другая с текстом описания (с включенным разбором TeX-их команд). Можно использовать непосредственно массивы строк, или накопление во внутренние массивы с помощью функции AddLegend() с последующим отображением. Положение легенды можно задать автоматически или вручную. Параметры @var{fnt} и @var{size} задают стиль и размер шрифта (см. @ref{Font settings}). Параметр @var{llen} задает относительную ширину примера линии. Ели стиль линии пустой, то соответствующий текст печатается без отступа. Если строка @var{fnt} содержит символ @samp{A}, то координаты легенды считаются относительно картинки (а не текущего subplot). Если строка @var{fnt} содержит символ @samp{#}, то рисуется прямоугольник вокруг легенды. @sref{Legend sample}
 
 @anchor{legend}
-@deftypefn {MGL command} {} legend [@code{pos=3} 'fnt'='#' @code{size=-0.8 llen=0.1}]
+@deftypefn {Команда MGL} {} legend [@code{pos=3} 'fnt'='#' @code{size=-0.8 llen=0.1}]
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Legend (@code{int} pos=@code{0x3}, @code{const char *}fnt=@code{"#"}, @code{float} size=@code{-0.8}, @code{float} llen=@code{0.1})
-@deftypefnx {C function} @code{void} mgl_legend (@code{HMGL} gr, @code{int} pos, @code{const char *}fnt, @code{float} size, @code{float} llen)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Legend (@code{int} pos=@code{0x3}, @code{const char *}fnt=@code{"#"}, @code{float} size=@code{-0.8}, @code{float} llen=@code{0.1})
+@deftypefnx {Функция С} @code{void} mgl_legend (@code{HMGL} gr, @code{int} pos, @code{const char *}fnt, @code{float} size, @code{float} llen)
 @end ifclear
 Рисует легенду из накопленных записей шрифтом @var{fnt} размером @var{size}. Параметр @var{pos} задает положение легенды: @samp{0} -- в нижнем левом углу, @samp{1} -- нижнем правом углу, @samp{2} -- верхнем левом углу, @samp{3} -- верхнем правом углу (по умолчанию). Строка @var{fnt} может содержать вет для прямоугольника (1-ый цвет), для его границы (2-ой цвет) и для текста (последний). Если указано менее 3 цветов, то цвет рёбер будет чёрным (2 и менее цвета), а цвет прямоугольника белым (1 и менее цвета). Прямоугольник рисуется если строка @var{fnt} содержит @samp{#}.
 @end deftypefn
 
-@deftypefn {MGL command} {} legend @code{x y} ['fnt'='#' @code{size=-1 llen=0.1}]
+@deftypefn {Команда MGL} {} legend @code{x y} ['fnt'='#' @code{size=-1 llen=0.1}]
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Legend (@code{float} x, @code{float} y, @code{const char *}fnt=@code{"#"}, @code{float} size=@code{-0.8}, @code{float} llen=@code{0.1})
-@deftypefnx {C function} @code{void} mgl_legend_pos (@code{HMGL} gr, @code{float} x, @code{float} y, @code{const char *}fnt, @code{float} size, @code{float} llen)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Legend (@code{float} x, @code{float} y, @code{const char *}fnt=@code{"#"}, @code{float} size=@code{-0.8}, @code{float} llen=@code{0.1})
+@deftypefnx {Функция С} @code{void} mgl_legend_pos (@code{HMGL} gr, @code{float} x, @code{float} y, @code{const char *}fnt, @code{float} size, @code{float} llen)
 @end ifclear
 Рисует легенду из накопленных записей шрифтом @var{fnt} размером @var{size}. Положение легенды задается параметрами @var{x}, @var{y}, которые полагаются нормированными в диапазоне [0,1].
 @end deftypefn
 
 @anchor{addlegend}
-@deftypefn {MGL command} {} addlegend 'text' 'stl'
+@deftypefn {Команда MGL} {} addlegend 'text' 'stl'
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} AddLegend (@code{const char *}text, @code{const char *}style)
-@deftypefnx {Method on @code{mglGraph}} @code{void} AddLegend (@code{const wchar_t *}text, @code{const char *}style)
-@deftypefnx {C function} @code{void} mgl_add_legend (@code{HMGL} gr, @code{const char *}text, @code{const char *}style)
-@deftypefnx {C function} @code{void} mgl_add_legendw (@code{HMGL} gr, @code{const wchar_t *}text, @code{const char *}style)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLegend (@code{const char *}text, @code{const char *}style)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLegend (@code{const wchar_t *}text, @code{const char *}style)
+@deftypefnx {Функция С} @code{void} mgl_add_legend (@code{HMGL} gr, @code{const char *}text, @code{const char *}style)
+@deftypefnx {Функция С} @code{void} mgl_add_legendw (@code{HMGL} gr, @code{const wchar_t *}text, @code{const char *}style)
 @end ifclear
 Добавляет описание @var{text} кривой со стилем @var{style} (см. @ref{Line styles}) во внутренний массив записей легенды.
 @end deftypefn
 
 @anchor{clearlegend}
-@deftypefn {MGL command} {} clearlegend
+@deftypefn {Команда MGL} {} clearlegend
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ClearLegend ()
-@deftypefnx {C function} @code{void} mgl_clear_legend (@code{HMGL} gr)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ClearLegend ()
+@deftypefnx {Функция С} @code{void} mgl_clear_legend (@code{HMGL} gr)
 @end ifclear
 Очищает внутренний массив записей легенды.
 @end deftypefn
 
 @anchor{legendmarks}
-@deftypefn {MGL command} {} legendmarks @code{val}
+@deftypefn {Команда MGL} {} legendmarks @code{val}
 @ifclear UDAV
 @deftypefnx {Метод класса @code{mglGraph}} @code{void} SetLegendMarks (@code{int} num)
 @deftypefnx {Функция С} @code{void} mgl_set_legend_marks (@code{HMGL} gr, @code{int} num)
@@ -1554,154 +1554,154 @@ gr.GetBGRN(bits, len(bits));
 Строка @var{pen} задает цвет и стиль линии и маркеров (см. @ref{Line styles}). По умолчанию (@code{pen=""}) рисуется сплошная линия с текущим цветом из палитры (см. @ref{Palette and colors}). Символ @samp{!} в строке задает использование нового цвета из палитры для каждой точки данных (не для всей кривой, как по умолчанию). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{1D samples}
 
 @anchor{plot}
-@deftypefn {MGL command} {} plot ydat ['stl'='']
-@deftypefnx {MGL command} {} plot xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} plot xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} plot ydat ['stl'='']
+@deftypefnx {Команда MGL} {} plot xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} plot xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_plot (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_plot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_plot_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_plot (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_plot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_plot_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют ломанную линию по точкам. См. также @ref{area}, @ref{step}, @ref{stem}, @ref{tube}, @ref{mark}, @ref{error}, @ref{belt}, @ref{tens}, @ref{tape}. @sref{Plot sample}
 @end deftypefn
 
 @anchor{radar}
-@deftypefn {MGL command} {} radar adat ['stl'='']
+@deftypefn {Команда MGL} {} radar adat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Radar (@code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_radar (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Radar (@code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_radar (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют radar chart, представляющий собой ломанную с вершинами на радиальных линиях (типа ломанной в полярных координатах). Параметр @var{value} в опциях @var{opt} задает дополнительный сдвиг данных (т.е. использование @var{a}+@var{value} вместо @var{a}). Если @var{pen} содержит @samp{#}, то рисуется "сетка" (радиальные линии). См. также @ref{plot}. @sref{Radar sample}
 @end deftypefn
 
 @anchor{step}
-@deftypefn {MGL command} {} step ydat ['stl'='']
-@deftypefnx {MGL command} {} step xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} step xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} step ydat ['stl'='']
+@deftypefnx {Команда MGL} {} step xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} step xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_step (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_step_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_step_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_step (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_step_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_step_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют ступеньки для точек массива. См. также @ref{plot}, @ref{stem}, @ref{tile}, @ref{boxs}. @sref{Step sample}
 @end deftypefn
 
 @anchor{tens}
-@deftypefn {MGL command} {} tens ydat cdat ['stl'='']
-@deftypefnx {MGL command} {} tens xdat ydat cdat ['stl'='']
-@deftypefnx {MGL command} {} tens xdat ydat zdat cdat ['stl'='']
+@deftypefn {Команда MGL} {} tens ydat cdat ['stl'='']
+@deftypefnx {Команда MGL} {} tens xdat ydat cdat ['stl'='']
+@deftypefnx {Команда MGL} {} tens xdat ydat zdat cdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglData &}y, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_tens (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tens_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglData &}y, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tens (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tens_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют ломанную линию по точкам с цветом, определяемым массивом @var{c} (типа графика натяжений). Строка @var{pen} задает цветовую схему (см. @ref{Color scheme}) и стиль линий и/или маркеров (см. @ref{Line styles}). См. также @ref{plot}, @ref{mesh}, @ref{fall}. @sref{Tens sample}
 @end deftypefn
 
 @anchor{tape}
-@deftypefn {MGL command} {} tape ydat ['stl'='']
-@deftypefnx {MGL command} {} tape xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} tape xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} tape ydat ['stl'='']
+@deftypefnx {Команда MGL} {} tape xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} tape xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_tape (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tape_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tape_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tape (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tape_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tape_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют ленты, которые вращаются вокруг кривой @{@var{x}[i], @var{y}[i], @var{z}[i]@} как её нормали. Начальная лента(ы) выбираются в плоскости x-y (для @samp{x} в @var{pen}) и/или y-z (для @samp{x} в @var{pen}). Ширина лент пропорциональна @code{SetBarWidth()}. См. также @ref{plot}, @ref{flow}, @ref{barwidth}. @sref{Tape sample}
 @end deftypefn
 
 @anchor{area}
-@deftypefn {MGL command} {} area ydat ['stl'='']
-@deftypefnx {MGL command} {} area xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} area xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} area ydat ['stl'='']
+@deftypefnx {Команда MGL} {} area xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} area xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_area (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_area_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_area_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_area (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_area_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_area_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют ломанную линию между точками и закрашивает её вниз до плоскости осей координат. Градиентная заливка используется если число цветов равно удвоенному число кривых. См. также @ref{plot}, @ref{bars}, @ref{stem}, @ref{region}. @sref{Area sample}
 @end deftypefn
 
 @anchor{region}
-@deftypefn {MGL command} {} region ydat1 ydat2 ['stl'='']
-@deftypefnx {MGL command} {} region xdat ydat1 ydat2 ['stl'='']
+@deftypefn {Команда MGL} {} region ydat1 ydat2 ['stl'='']
+@deftypefnx {Команда MGL} {} region xdat ydat1 ydat2 ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglData &}x, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_region (@code{HMGL} gr, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglData &}x, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_region (@code{HMGL} gr, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции закрашивают область между 2 кривыми. Градиентная заливка используется если число цветов равно удвоенному число кривых. Если @var{pen} содержит @samp{i}, то закрашивается только область y1<y<y2, в противном случае будет закрашена и область y2<y<y1. См. также @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
 @end deftypefn
 
 @anchor{stem}
-@deftypefn {MGL command} {} stem ydat ['stl'='']
-@deftypefnx {MGL command} {} stem xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} stem xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} stem ydat ['stl'='']
+@deftypefnx {Команда MGL} {} stem xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} stem xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_stem (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_stem_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_stem_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_stem (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_stem_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_stem_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют вертикальные линии из точек до плоскости осей координат. См. также @ref{area}, @ref{bars}, @ref{plot}, @ref{mark}. @sref{Stem sample}
 @end deftypefn
 
 @anchor{bars}
-@deftypefn {MGL command} {} bars ydat ['stl'='']
-@deftypefnx {MGL command} {} bars xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} bars xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} bars ydat ['stl'='']
+@deftypefnx {Команда MGL} {} bars xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} bars xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_bars (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_bars_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_bars_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_bars (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_bars_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_bars_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют вертикальные полосы (прямоугольники) из точек до плоскости осей координат. Если строка @var{pen} содержит символ @samp{a}, то линии рисуются одна поверх другой. Если строка содержит символ @samp{f}, то рисуется график типа waterfall для определения кумулятивного эффекта последовательности положительных и отрицательных значений. Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. См. также @ref{barh}, @ref{cones}, @ref{area}, @ref{stem}, @ref{chart}, @ref{barwidth}. @sref{Bars sample}
 @end deftypefn
 
 @anchor{barh}
-@deftypefn {MGL command} {} barh vdat ['stl'='']
-@deftypefnx {MGL command} {} barh ydat vdat ['stl'='']
+@deftypefn {Команда MGL} {} barh vdat ['stl'='']
+@deftypefnx {Команда MGL} {} barh ydat vdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Barh (@code{const mglData &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Barh (@code{const mglData &}y, @code{const mglData &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_barh (@code{HMGL} gr, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_barh_xy (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Barh (@code{const mglData &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Barh (@code{const mglData &}y, @code{const mglData &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_barh (@code{HMGL} gr, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_barh_xy (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют горизонтальные полосы (прямоугольники) из точек до плоскости осей координат. Если строка @var{pen} содержит символ @samp{a}, то линии рисуются одна поверх другой. Если строка содержит символ @samp{f}, то рисуется график типа waterfall для определения кумулятивного эффекта последовательности положительных и отрицательных значений. Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. См. также @ref{bars}, @ref{barwidth}. @sref{Barh sample}
 @end deftypefn
 
 @anchor{cones}
-@deftypefn {MGL command} {} cones ydat ['stl'='']
-@deftypefnx {MGL command} {} cones xdat ydat ['stl'='']
-@deftypefnx {MGL command} {} cones xdat ydat zdat ['stl'='']
+@deftypefn {Команда MGL} {} cones ydat ['stl'='']
+@deftypefnx {Команда MGL} {} cones xdat ydat ['stl'='']
+@deftypefnx {Команда MGL} {} cones xdat ydat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_cones (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_cones_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_cones_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cones (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cones_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cones_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют конусы из точек до плоскости осей координат. Если строка @var{pen} содержит символ @samp{a}, то линии рисуются одна поверх другой. Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. См. также @ref{bars}, @ref{barwidth}. @sref{Cones sample}
 @end deftypefn
@@ -1709,152 +1709,152 @@ gr.GetBGRN(bits, len(bits));
 
 
 @anchor{chart}
-@deftypefn {MGL command} {} chart adat ['col'='']
+@deftypefn {Команда MGL} {} chart adat ['col'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Chart (@code{const mglData &}a, @code{const char *}col=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_chart (@code{HMGL} gr, @code{HCDT} a, @code{const char *}col, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Chart (@code{const mglData &}a, @code{const char *}col=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_chart (@code{HMGL} gr, @code{HCDT} a, @code{const char *}col, @code{const char *}opt)
 @end ifclear
 Рисует цветные полосы (пояса) для массива данных @var{a}. Число полос равно числу строк @var{a} (равно @var{a.ny}). Цвет полос поочерёдно меняется из цветов указанных в @var{col} или в палитре (см. @ref{Palette and colors}). Пробел в цветах соответствует прозрачному "цвету", т.е. если @var{col} содержит пробел(ы), то соответствующая полоса не рисуется. Ширина полосы пропорциональна значению элемента в @var{a}. График строится только для массивов не содержащих отрицательных значений. Если строка @var{col} содержит @samp{#}, то рисуется также чёрная граница полос. График выглядит лучше в (после вращения системы координат) и/или в полярной системе координат (становится Pie chart). @sref{Chart sample}
 @end deftypefn
 
 @anchor{boxplot}
-@deftypefn {MGL command} {} boxplot adat ['stl'='']
-@deftypefnx {MGL command} {} boxplot xdat adat ['stl'='']
+@deftypefn {Команда MGL} {} boxplot adat ['stl'='']
+@deftypefnx {Команда MGL} {} boxplot xdat adat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} BoxPlot (@code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} BoxPlot (@code{const mglData &}x, @code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_boxplot (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_boxplot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} BoxPlot (@code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} BoxPlot (@code{const mglData &}x, @code{const mglData &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_boxplot (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_boxplot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют boxplot (называемый также как box-and-whisker diagram или как "ящик с усами") в точках @var{x}[i] на плоскости @var{z} = @var{zVal} (по умолчанию @var{z}=@var{Min.z}). Это график, компактно изображающий распределение вероятностей @var{a}[i,j] (минимум, нижний квартиль (Q1), медиана (Q2), верхний квартиль (Q3) и максимум) вдоль второго (j-го) направления. См. также @ref{plot}, @ref{error}, @ref{bars}, @ref{barwidth}. @sref{BoxPlot sample}
 @end deftypefn
 
 @anchor{candle}
-@deftypefn {MGL command} {} candle vdat1 ['stl'='']
-@deftypefnx {MGL command} {} candle vdat1 vdat2 ['stl'='']
-@deftypefnx {MGL command} {} candle vdat1 ydat1 ydat2 ['stl'='']
-@deftypefnx {MGL command} {} candle vdat1 vdat2 ydat1 ydat2 ['stl'='']
-@deftypefnx {MGL command} {} candle xdat vdat1 vdat2 ydat1 ydat2 ['stl'='']
-@ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}v2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}v2, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglData &}x, @code{const mglData &}v1, @code{const mglData &}v2, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_candle (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
+@deftypefn {Команда MGL} {} candle vdat1 ['stl'='']
+@deftypefnx {Команда MGL} {} candle vdat1 vdat2 ['stl'='']
+@deftypefnx {Команда MGL} {} candle vdat1 ydat1 ydat2 ['stl'='']
+@deftypefnx {Команда MGL} {} candle vdat1 vdat2 ydat1 ydat2 ['stl'='']
+@deftypefnx {Команда MGL} {} candle xdat vdat1 vdat2 ydat1 ydat2 ['stl'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}v2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglData &}v1, @code{const mglData &}v2, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglData &}x, @code{const mglData &}v1, @code{const mglData &}v2, @code{const mglData &}y1, @code{const mglData &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_candle (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют candlestick chart в точках @var{x}[i]. Этот график показывает прямоугольником ("свечой") диапазон изменения величины. Прозрачная (белая) свеча соответствует росту величины @var{v1}[i]<@var{v2}[i], чёрная -- уменьшению. "Тени" показывают минимальное @var{y1} и максимальное @var{y2} значения. Если @var{v2} отсутствует, то он определяется как @var{v2}[i]=@var{v1}[i+1]. См. также @ref{plot}, @ref{bars}, @ref{barwidth}. @sref{Candle sample}
 @end deftypefn
 
 
 @anchor{error}
-@deftypefn {MGL command} {} error ydat yerr ['stl'='']
-@deftypefnx {MGL command} {} error xdat ydat yerr ['stl'='']
-@deftypefnx {MGL command} {} error xdat ydat xerr yerr ['stl'='']
+@deftypefn {Команда MGL} {} error ydat yerr ['stl'='']
+@deftypefnx {Команда MGL} {} error xdat ydat yerr ['stl'='']
+@deftypefnx {Команда MGL} {} error xdat ydat xerr yerr ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglData &}y, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ex, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_error (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_error_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_error_exy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ex, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglData &}y, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ex, @code{const mglData &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_error (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_error_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_error_exy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ex, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют размер ошибки в точках @{@var{x}[i], @var{y}[i]@} на плоскости @var{z} = @var{zVal} (по умолчанию @var{z}=@var{Min.z}). Такой график полезен для отображения ошибки эксперимента, вычислений и пр. Если @var{pen} содержит @samp{@@}, то будут использованы большие полупрозрачные маркеры. См. также @ref{plot}, @ref{mark}. @sref{Error sample}
 @end deftypefn
 
 @anchor{mark}
-@deftypefn {MGL command} {} mark ydat rdat ['stl'='']
-@deftypefnx {MGL command} {} mark xdat ydat rdat ['stl'='']
-@deftypefnx {MGL command} {} mark xdat ydat zdat rdat ['stl'='']
+@deftypefn {Команда MGL} {} mark ydat rdat ['stl'='']
+@deftypefnx {Команда MGL} {} mark xdat ydat rdat ['stl'='']
+@deftypefnx {Команда MGL} {} mark xdat ydat zdat rdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_mark_y (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_mark_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_mark_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_mark_y (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_mark_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_mark_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют маркеры размером @var{r}*@var{MarkSize} (см. @ref{Default sizes}) в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Для рисования маркеров одинакового размера можно использовать функцию @ref{plot} с невидимой линией (со стилем содержащим @samp{ }). Для маркеров с размером как у координат можно использовать @ref{error} со стилем @samp{@@}. См. также @ref{plot}, @ref{textmark}, @ref{error}, @ref{stem}. @sref{Mark sample}
 @end deftypefn
 
 @anchor{textmark}
-@deftypefn {MGL command} {} textmark ydat 'txt' ['stl'='']
-@deftypefnx {MGL command} {} textmark ydat rdat 'txt' ['stl'='']
-@deftypefnx {MGL command} {} textmark xdat ydat rdat 'txt' ['stl'='']
-@deftypefnx {MGL command} {} textmark xdat ydat zdat rdat 'txt' ['stl'='']
-@ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_textmark (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmarkw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmark_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmarkw_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmark_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmarkw_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmark_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_textmarkw_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefn {Команда MGL} {} textmark ydat 'txt' ['stl'='']
+@deftypefnx {Команда MGL} {} textmark ydat rdat 'txt' ['stl'='']
+@deftypefnx {Команда MGL} {} textmark xdat ydat rdat 'txt' ['stl'='']
+@deftypefnx {Команда MGL} {} textmark xdat ydat zdat rdat 'txt' ['stl'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}y, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_textmark (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmarkw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmark_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmarkw_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmark_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmarkw_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmark_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_textmarkw_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
 Функции рисуют текст @var{text} как маркер с размером пропорциональным @var{r}*@var{MarkSize} (см. @ref{Default sizes}) в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. См. также @ref{plot}, @ref{mark}, @ref{stem}. @sref{TextMark sample}
 @end deftypefn
 
 @anchor{label}
-@deftypefn {MGL command} {} label ydat 'txt' ['stl'='']
-@deftypefnx {MGL command} {} label xdat ydat 'txt' ['stl'='']
-@deftypefnx {MGL command} {} label xdat ydat zdat 'txt' ['stl'='']
-@ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_label (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_labelw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_label_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_labelw_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefn {Команда MGL} {} label ydat 'txt' ['stl'='']
+@deftypefnx {Команда MGL} {} label xdat ydat 'txt' ['stl'='']
+@deftypefnx {Команда MGL} {} label xdat ydat zdat 'txt' ['stl'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_label (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_labelw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_label_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_labelw_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
 @end ifclear
 Функции выводят текстовую строку @var{txt} в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если строка @var{txt} содержит @samp{%x}, @samp{%y}, @samp{%z} или @samp{%n}, то они будут заменены на значения соответствующих координат или на номер точки. См. также @ref{plot}, @ref{mark}, @ref{textmark}. @sref{Label sample}
 @end deftypefn
 
 @anchor{tube}
-@deftypefn {MGL command} {} tube ydat rdat ['stl'='']
-@deftypefnx {MGL command} {} tube ydat @code{rval} ['stl'='']
-@deftypefnx {MGL command} {} tube xdat ydat rdat ['stl'='']
-@deftypefnx {MGL command} {} tube xdat ydat @code{rval} ['stl'='']
-@deftypefnx {MGL command} {} tube xdat ydat zdat rdat ['stl'='']
-@deftypefnx {MGL command} {} tube xdat ydat zdat @code{rval} ['stl'='']
-@ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}y, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_tube_r (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tube (@code{HMGL} gr, @code{HCDT} y, @code{float} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tube_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tube_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{float} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tube_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tube_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{float} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefn {Команда MGL} {} tube ydat rdat ['stl'='']
+@deftypefnx {Команда MGL} {} tube ydat @code{rval} ['stl'='']
+@deftypefnx {Команда MGL} {} tube xdat ydat rdat ['stl'='']
+@deftypefnx {Команда MGL} {} tube xdat ydat @code{rval} ['stl'='']
+@deftypefnx {Команда MGL} {} tube xdat ydat zdat rdat ['stl'='']
+@deftypefnx {Команда MGL} {} tube xdat ydat zdat @code{rval} ['stl'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}y, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{float} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tube_r (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tube (@code{HMGL} gr, @code{HCDT} y, @code{float} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tube_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tube_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{float} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tube_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tube_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{float} r, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют трубу радиуса @var{r}[i] вдоль кривой между точками @{@var{x}[i], @var{y}[i], @var{z}[i]@}. См. также @ref{plot}. @sref{Tube sample}
 @end deftypefn
 
 @anchor{torus}
-@deftypefn {MGL command} {} torus rdat zdat ['stl'='']
+@deftypefn {Команда MGL} {} torus rdat zdat ['stl'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Torus (@code{const mglData &}r, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_torus (@code{HMGL} gr, @code{HCDT} r, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Torus (@code{const mglData &}r, @code{const mglData &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_torus (@code{HMGL} gr, @code{HCDT} r, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
 @end ifclear
 Функции рисуют поверхность вращения кривой @{@var{r}, @var{z}@} относительно оси. Если строка @var{pen} содержит @samp{x} или @samp{z}, то ось вращения будет выбрана в указанном направлении (по умолчанию вдоль оси y). См. также @ref{plot}, @ref{axial}. @sref{Torus sample}
 @end deftypefn
@@ -1883,212 +1883,212 @@ gr.GetBGRN(bits, len(bits));
 
 
 @anchor{surf}
-@deftypefn {MGL command} {} surf zdat ['sch'='']
-@deftypefnx {MGL command} {} surf xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} surf zdat ['sch'='']
+@deftypefnx {Команда MGL} {} surf xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Surf (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Surf (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_surf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_surf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Если @var{sch} содержит @samp{#}, то рисуется сетка на поверхности. См. также @ref{mesh}, @ref{dens}, @ref{belt}, @ref{tile}, @ref{boxs}, @ref{surfc}, @ref{surfa}. @sref{Surf sample}
 @end deftypefn
 
 @anchor{mesh}
-@deftypefn {MGL command} {} mesh zdat ['sch'='']
-@deftypefnx {MGL command} {} mesh xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} mesh zdat ['sch'='']
+@deftypefnx {Команда MGL} {} mesh xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Mesh (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Mesh (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_mesh (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_mesh_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mesh (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mesh (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_mesh (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_mesh_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует сетчатую поверхность, заданную параметрически @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. См. также @ref{surf}, @ref{fall}, @ref{meshnum}, @ref{cont}, @ref{tens}. @sref{Mesh sample}
 @end deftypefn
 
 @anchor{fall}
-@deftypefn {MGL command} {} fall zdat ['sch'='']
-@deftypefnx {MGL command} {} fall xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} fall zdat ['sch'='']
+@deftypefnx {Команда MGL} {} fall xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Fall (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Fall (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_fall (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_fall_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fall (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fall (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_fall (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_fall_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует водопад для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. График удобен для построения нескольких кривых, сдвинутых вглубь друг относительно друга. Если @var{sch} содержит @samp{x}, то линии рисуются вдоль оси x, иначе (по умолчанию) вдоль оси y. См. также @ref{belt}, @ref{mesh}, @ref{tens}, @ref{meshnum}. @sref{Fall sample}
 @end deftypefn
 
 @anchor{belt}
-@deftypefn {MGL command} {} belt zdat ['sch'='']
-@deftypefnx {MGL command} {} belt xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} belt zdat ['sch'='']
+@deftypefnx {Команда MGL} {} belt xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Belt (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Belt (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_belt (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_belt_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Belt (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Belt (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_belt (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_belt_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует ленточки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. График может использоваться как 3d обобщение графика @ref{plot}. Если @var{sch} содержит @samp{x}, то ленточки рисуются вдоль оси x, иначе (по умолчанию) вдоль оси y. См. также @ref{fall}, @ref{surf}, @ref{plot}, @ref{meshnum}. @sref{Belt sample}
 @end deftypefn
 
 @anchor{boxs}
-@deftypefn {MGL command} {} boxs zdat ['sch'='']
-@deftypefnx {MGL command} {} boxs xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} boxs zdat ['sch'='']
+@deftypefnx {Команда MGL} {} boxs xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Boxs (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Boxs (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_boxs (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_boxs_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Boxs (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Boxs (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_boxs (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_boxs_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует вертикальные ящики для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. См. также @ref{surf}, @ref{dens}, @ref{tile}, @ref{step}. @sref{Boxs sample}
 @end deftypefn
 
 @anchor{tile}
-@deftypefn {MGL command} {} tile zdat ['sch'='']
-@deftypefnx {MGL command} {} tile xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} tile zdat ['sch'='']
+@deftypefnx {Команда MGL} {} tile xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tile (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Tile (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_tile (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_tile_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tile (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tile (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tile (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tile_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует плитки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. График может использоваться как 3d обобщение @ref{step}. См. также @ref{surf}, @ref{boxs}, @ref{step}, @ref{tiles}. @sref{Tile sample}
 @end deftypefn
 
 @anchor{dens}
-@deftypefn {MGL command} {} dens zdat ['sch'='']
-@deftypefnx {MGL command} {} dens xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} dens zdat ['sch'='']
+@deftypefnx {Команда MGL} {} dens xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Dens (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Dens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {C function} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{float} zVal=@code{NAN})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{float} zVal=@code{NAN})
+@deftypefnx {Функция С} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует график плотности для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} = @var{Min}.z. Если @var{sch} содержит @samp{#}, то рисуется сетка. См. также @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
 @end deftypefn
 
 @anchor{cont}
-@deftypefn {MGL command} {} cont vdat zdat ['sch'='']
-@deftypefnx {MGL command} {} cont vdat xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} cont vdat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} cont vdat xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_cont__val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont__val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} cont zdat ['sch'='']
-@deftypefnx {MGL command} {} cont xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} cont zdat ['sch'='']
+@deftypefnx {Команда MGL} {} cont xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_cont (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_cont_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
 @anchor{contf}
-@deftypefn {MGL command} {} contf vdat zdat ['sch'='']
-@deftypefnx {MGL command} {} contf vdat xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contf vdat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contf vdat xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} contf zdat ['sch'='']
-@deftypefnx {MGL command} {} contf xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contf zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contf xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
 @anchor{contd}
-@deftypefn {MGL command} {} contd vdat zdat ['sch'='']
-@deftypefnx {MGL command} {} contd vdat xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contd vdat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contd vdat xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Строка @var{sch} задает цвета контуров: цвет k-го контура определяется как k-ый цвет строки. См. также @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} contd zdat ['sch'='']
-@deftypefnx {MGL command} {} contd xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contd zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contd xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contd (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contd_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contd (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contd_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
 @anchor{contv}
-@deftypefn {MGL command} {} contv vdat zdat ['sch'='']
-@deftypefnx {MGL command} {} contv vdat xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contv vdat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contv vdat xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует вертикальные цилиндры от линий уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{cont}, @ref{contf}. @sref{ContV sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} contv zdat ['sch'='']
-@deftypefnx {MGL command} {} contv xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} contv zdat ['sch'='']
+@deftypefnx {Команда MGL} {} contv xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_contv (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_contv_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contv (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contv_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
 @anchor{axial}
-@deftypefn {MGL command} {} axial vdat zdat ['sch'='']
-@deftypefnx {MGL command} {} axial vdat xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} axial vdat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} axial vdat xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_axial_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_axial_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglData &}v, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_axial_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_axial_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует поверхность вращения линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если строка содержит символы @samp{x}, @samp{y} или @samp{z}, то ось вращения устанавливается в указанное направление. См. также @ref{cont}, @ref{contf}, @ref{torus}, @ref{surf3}. @sref{Axial sample}
 @end deftypefn
 
-@deftypefn {MGL command} {} axial zdat ['sch'='']
-@deftypefnx {MGL command} {} axial xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} axial zdat ['sch'='']
+@deftypefnx {Команда MGL} {} axial xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
-@deftypefnx {C function} @code{void} mgl_axial (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_axial_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
+@deftypefnx {Функция С} @code{void} mgl_axial (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_axial_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @var{value} в опциях @var{opt} (по умолчанию 3).
 @end deftypefn
 
 @anchor{grid2}
-@deftypefn {MGL command} {} grid2 zdat ['sch'='']
-@deftypefnx {MGL command} {} grid2 xdat ydat zdat ['sch'='']
+@deftypefn {Команда MGL} {} grid2 zdat ['sch'='']
+@deftypefnx {Команда MGL} {} grid2 xdat ydat zdat ['sch'='']
 @ifclear UDAV
-@deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
-@deftypefnx {C function} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
-@deftypefnx {C function} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
 @end ifclear
 Рисует плоскую сету для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} = @var{Min}.z. См. также @ref{dens}, @ref{cont}, @ref{contf}, @ref{meshnum}.
 @end deftypefn
@@ -2097,880 +2097,738 @@ gr.GetBGRN(bits, len(bits));
 @c ##################################################################
 @node 3D plotting, Dual plotting, 2D plotting, MathGL core
 @section 3D графики
-
-Эти функции строят графики для трехмерных (3D) массивов. Трехмерными считаются массивы, зависящие от трех параметров (индексов) подобно матрице @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}. Есть 5 основных типов 3D графиков: поверхность постоянного уровня (Surf3), график плотности на срезе (Dens3), линии уровня на срезе (Cont3), закрашенные контуры уровня на срезе (ContF3) и график объемной прозрачности типа облака (Cloud). В функциях Cont3(), ContF3() и Surf3() значения уровней можно задавать автоматически и вручную. Можно также нарисовать на срезе сетку (Grid3) по массиву данных для улучшения вида графика плотности или линий уровня. Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой @xref{Color scheme}. @sref{3D plot sample}
-
-@menu
-* Surf3::
-* Dens3::
-* Cont3::
-* ContF3::
-* Grid3::
-* Cloud::
-* Beam::
-@end menu
-
-@c ==================================================================
-@node Surf3, Dens3, , 3D plotting
-@subsection Surf3
 @cindex Surf3
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3_xyz_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl)
-Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). Замечу, что возможно некорректная отрисовка граней вследствие неопределенности построения сечения если поверхность пересекает ячейку данных 2 и более раз. См. также @ref{Cloud}, @ref{Dens3}, @ref{Surf3C}, @ref{Surf3A}, @ref{Axial}. @sref{Surf3 sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{float} val, @code{const mglData &}a, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} a, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl, @code{int} num)
-Рисует @var{num} поверхностей уровня равномерно распределенных в интервале [@var{Cmin}, @var{Cmax}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3 (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node Dens3, Cont3, Surf3, 3D plotting
-@subsection Dens3
 @cindex Dens3
-@cindex DensA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dens3_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl)
-Рисует график плотности для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). См. также @ref{Cont3}, @ref{ContF3}, @ref{Dens}, @ref{Grid3}. @sref{Dens3 sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dens3 (@code{HMGL} gr, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} DensA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dens3_all_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl)
-Рисует графики плотности на всех центральных срезах 3d данных, заданных параметрически.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} DensA (@code{const mglData &}a, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dens3_all (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node Cont3, ContF3, Dens3, 3D plotting
-@subsection Cont3
 @cindex Cont3
-@cindex ContA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_cont3_xyz_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl)
-Рисует линии уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Строка @var{stl} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). См. также @ref{Dens3}, @ref{ContF3}, @ref{Cont}, @ref{Grid3}. @sref{Cont3 sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}v, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_cont3_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont3_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl, @code{int} num)
-Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в интервале [@var{Cmin}, @var{Cmax}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont3 (@code{HMGL} gr, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont3_all_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl, @code{int} num)
-Рисует линии уровня на всех центральных срезах 3d данных, заданных параметрически.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContA (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont3_all (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node ContF3, Grid3, Cont3, 3D plotting
-@subsection ContF3
 @cindex ContF3
-@cindex ContFA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContF3 (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_contf3_xyz_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl)
-Рисует закрашенные линии (контуры) уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). См. также @ref{Dens3}, @ref{Cont3}, @ref{ContF}, @ref{Grid3}. @sref{ContF3 sample}
-@end deftypefn
+@cindex Grid3
+@cindex Cloud
+@cindex Beam
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContF3 (@code{const mglData &}v, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_contf3_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
+Эти функции строят графики для трехмерных (3D) массивов. Трёхмерными считаются массивы, зависящие от трёх параметров (индексов) подобно матрице @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}. По умолчанию (если отсутствуют) значения @var{x}, @var{y}, @var{z} равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} или @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Массивы @var{x}, @var{y} и @var{z} могут быть векторами (не матрицами как @var{a}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{3D samples}
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContF3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf3_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl, @code{int} num)
-Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в интервале [@var{Cmin}, @var{Cmax}].
-@end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContF3 (@code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf3 (@code{HMGL} gr, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf3_all_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl, @code{int} num)
-Рисует закрашенные линии (контуры) уровня на всех центральных срезах 3d данных, заданных параметрически.
+@anchor{surf3}
+@deftypefn {Команда MGL} {} surf3 adat @code{val} ['sch'='']
+@deftypefnx {Команда MGL} {} surf3 xdat ydat zdat adat @code{val} ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{float} val, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3_val (@code{HMGL} gr, @code{float} val, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3_xyz_val (@code{HMGL} gr, @code{float} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Замечу, что возможно некорректная отрисовка граней вследствие неопределённости построения сечения если поверхность пересекает ячейку данных 2 и более раз. См. также @ref{cloud}, @ref{dens3}, @ref{surf3c}, @ref{surf3a}, @ref{axial}. @sref{Surf3 sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFA (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf3_all (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@deftypefn {Команда MGL} {} surf3 adat ['sch'='']
+@deftypefnx {Команда MGL} {} surf3 xdat ydat zdat adat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @var{value} в опциях @var{opt} (по умолчанию 3).
 @end deftypefn
 
-@c ==================================================================
-@node Grid3, Cloud, ContF3, 3D plotting
-@subsection Grid3
-@cindex Grid3
-@cindex GridA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_grid3_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}stl)
-Рисует сетку для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). См. также @ref{Cont3}, @ref{ContF3}, @ref{Dens3}, @ref{Grid}.
+@anchor{cloud}
+@deftypefn {Команда MGL} {} cloud adat ['sch'='']
+@deftypefnx {Команда MGL} {} cloud xdat ydat zdat adat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cloud (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cloud_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует облачный график для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График состоит из кубиков с цветом и прозрачностью пропорциональной значениям @var{a}. Результат похож на облако -- малые значения прозрачны, а большие нет. Число кубиков зависит от @ref{meshnum}. Если @var{sch} содержит @samp{.}, то будет построен график более низкого качества, но с заметно меньшим использованием памяти. Если @var{sch} содержит @samp{!}, то прозрачность будет инвертирована, т.е. области с более высокими значениями будут более прозрачны, а с более низким -- менее прозрачны. См. также @ref{surf3}, @ref{meshnum}. @sref{Cloud sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglData &}a, @code{char} dir, @code{int} sVal=@code{-1}, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_grid3 (@code{HMGL} gr, @code{const HMDT} a, @code{char} dir, @code{int} sVal, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@anchor{dens3}
+@deftypefn {Команда MGL} {} dens3 adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} dens3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_dens3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dens3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Рисует график плотности для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. См. также @ref{cont3}, @ref{contf3}, @ref{dens}, @ref{grid3}. @sref{Dens3 sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} GridA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_grid3_all_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl)
-Рисует сетку на всех центральных срезах 3d данных, заданных параметрически.
+@anchor{cont3}
+@deftypefn {Команда MGL} {} cont3 vdat adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} cont3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Рисует линии уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens3}, @ref{contf3}, @ref{cont}, @ref{grid3}. @sref{Cont3 sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} GridA (@code{const mglData &}a, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_grid3_all (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@deftypefn {Команда MGL} {} cont3 adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} cont3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Аналогично предыдущему для @var{num} линий уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
-@c ==================================================================
-@node Cloud, Beam, Grid3, 3D plotting
-@subsection Cloud
-@cindex Cloud
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} alpha=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_cloud_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}stl, @code{float} alpha=@code{1})
-Рисует облачный график для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График состоит из кубиков с цветом и прозрачностью пропорциональной значениям @var{a}. Результат похож на облако -- малые значения прозрачны, а большие нет. Число кубиков зависит от @ref{MeshNum}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Параметр @var{alpha} меняет общую прозрачность графика. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). См. также @ref{Surf3}. @sref{Cloud sample}
+@anchor{contf3}
+@deftypefn {Команда MGL} {} contf3 vdat adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} contf3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglData &}v, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Рисует закрашенные линии (контуры) уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. Если @var{stl} содержит @samp{#}, то на срезе рисуется сетка. См. также @ref{dens3}, @ref{cont3}, @ref{contf}, @ref{grid3}. @sref{Cont3 sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} alpha=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_cloud (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} alpha=@code{1})
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@deftypefn {Команда MGL} {} contf3 adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} contf3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Аналогично предыдущему для @var{num} закрашенных линий (контуров) уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @var{value} в опциях @var{opt} (по умолчанию 7).
 @end deftypefn
 
-@c ==================================================================
-@node Beam, , Cloud, 3D plotting
-@subsection Beam
-@cindex Beam
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Beam (@code{float} val, @code{const mglData &}tr, @code{const mglData &}g1, @code{const mglData &}g2, @code{const mglData &}a, @code{float} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_beam_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} tr, @code{const HMDT} g1, @code{const HMDT} g2, @code{const HMDT} a, @code{float} r, @code{const char *}stl, @code{int} flag)
-Рисует поверхность уровня для 3d массива @var{a} при постоянном значении @var{a}=@var{val}. Это специальный тип графика для @var{a} заданного в сопровождающей системе координат вдоль кривой @var{tr} с ортами @var{g1}, @var{g2} и с поперечным размером @var{r}. Переменная @var{flag} -- битовый флаг: @samp{0x1} - рисовать в сопровождающих (не лабораторных) координатах; @samp{0x2} - рисовать проекцию на плоскость @math{\rho-z}; @samp{0x4} - рисовать нормированное в каждом сечении поле. Размеры массивов по 1-му индексу @var{tr}, @var{g1}, @var{g2} должны быть nx>2. Размеры массивов по 2-му индексу @var{tr}, @var{g1}, @var{g2} и размер по 3-му индексу массива @var{a} должны быть одинаковы. См. также @ref{Surf3}.
+@anchor{grid3}
+@deftypefn {Команда MGL} {} grid3 adat ['sch'='' @code{sval=-1}]
+@deftypefnx {Команда MGL} {} grid3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{float} sVal=@code{-1}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_grid3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_grid3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Рисует сетку для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @var{dir}=@{@samp{x}, @samp{y}, @samp{z}@}. См. также @ref{cont3}, @ref{contf3}, @ref{dens3}, @ref{grid2}, @ref{meshnum}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Beam (@code{const mglData &}tr, @code{const mglData &}g1, @code{const mglData &}g2, @code{const mglData &}a, @code{float} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_beam (@code{HMGL} gr, @code{const HMDT} tr, @code{const HMDT} g1, @code{const HMDT} g2, @code{const HMDT} a, @code{float} r, @code{const char *}stl, @code{int} flag=@code{0}, @code{int} num=@code{3})
-Рисует @var{num} равномерно распределенных в интервале [@var{Cmin}, @var{Cmax}] поверхностей уровня 3d массива в сопровождающей системе координат.
+@anchor{beam}
+@deftypefn {Команда MGL} {} beam tr g1 g2 adat @code{rval} ['sch'='' @code{flag=0 num=3}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Beam (@code{const mglData &}tr, @code{const mglData &}g1, @code{const mglData &}g2, @code{const mglData &}a, @code{float} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0}, @code{int} num=@code{3})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Beam (@code{float} val, @code{const mglData &}tr, @code{const mglData &}g1, @code{const mglData &}g2, @code{const mglData &}a, @code{float} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0})
+@deftypefnx {Функция С} @code{void} mgl_beam (@code{HMGL} gr, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{float} r, @code{const char *}stl, @code{int} flag, @code{int} num)
+@deftypefnx {Функция С} @code{void} mgl_beam_val (@code{HMGL} gr, @code{float} val, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{float} r, @code{const char *}stl, @code{int} flag)
+@end ifclear
+Рисует поверхность уровня для 3d массива @var{a} при постоянном значении @var{a}=@var{val}. Это специальный тип графика для @var{a} заданного в сопровождающей системе координат вдоль кривой @var{tr} с ортами @var{g1}, @var{g2} и с поперечным размером @var{r}. Переменная @var{flag} -- битовый флаг: @samp{0x1} - рисовать в сопровождающих (не лабораторных) координатах; @samp{0x2} - рисовать проекцию на плоскость @math{\rho-z}; @samp{0x4} - рисовать нормированное в каждом сечении поле. Размеры массивов по 1-му индексу @var{tr}, @var{g1}, @var{g2} должны быть nx>2. Размеры массивов по 2-му индексу @var{tr}, @var{g1}, @var{g2} и размер по 3-му индексу массива @var{a} должны быть одинаковы. См. также @ref{surf3}.
 @end deftypefn
 
 
-
 @c ##################################################################
 @node Dual plotting, Vector fields, 3D plotting, MathGL core
 @section Парные графики
-
-Эти функции строят графики для двух связанных массивов. Есть несколько основных типов 3D графиков: поверхность и поверхность уровня с окраской по второму массиву (SurfC, Surf3C), поверхность и поверхность уровня с прозрачностью по второму массиву (SurfA, Surf3A), плитки переменного размера (TileS), диаграмма точечного отображения (Map), STFA диаграмма (STFA). В функциях Surf3A() и Surf3C() значения уровней можно задавать автоматически и вручную. Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой @xref{Color scheme}.
-
-@menu
-* SurfC::
-* Surf3C::
-* SurfA::
-* Surf3A::
-* TileS::
-* Map::
-* STFA::
-@end menu
-
-@c ==================================================================
-@node SurfC, Surf3C, , Dual plotting
-@subsection SurfC
 @cindex SurfC
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surfc_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. Все размеры массивов @var{z} и @var{c} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=z.nx && y.nx=z.ny} или @code{x.nx=y.nx=z.nx && x.ny=y.ny=z.ny}. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{z}). График строится для каждого z среза данных. См. также @ref{Surf}, @ref{SurfA}, @ref{Surf3C}. @sref{SurfC sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surfc (@code{HMGL} gr, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-
-@c ==================================================================
-@node Surf3C, SurfA, SurfC, Dual plotting
-@subsection Surf3C
-@cindex Surf3C
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}stl)
-Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично Surf3(), но цвет задается массивом @var{c}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Все размеры массивов @var{z} и @var{c} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). Замечу, что возможно некорректная отрисовка граней вследствие неопределенности построения сечения если поверхность пересекает ячейку данных 2 и более раз. См. также @ref{Surf3}, @ref{SurfC}, @ref{Surf3A}. @sref{Surf3C sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{float} val, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3c_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}stl=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}stl, @code{int} num)
-Рисует @var{num} поверхностей уровня равномерно распределенных в интервале [@var{Cmin}, @var{Cmax}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3c (@code{HMGL} gr, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-
-@c ==================================================================
-@node SurfA, Surf3A, Surf3C, Dual plotting
-@subsection SurfA
 @cindex SurfA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surfa_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с прозрачностью, заданным массивом @var{c}[i,j]. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. Все размеры массивов @var{z} и @var{c} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=z.nx && y.nx=z.ny} или @code{x.nx=y.nx=z.nx && x.ny=y.ny=z.ny}. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{z}). График строится для каждого z среза данных. См. также @ref{Surf}, @ref{SurfC}, @ref{Surf3A}, @ref{TileS}. @sref{SurfA sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surfa (@code{HMGL} gr, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-
-@c ==================================================================
-@node Surf3A, TileS, SurfA, Dual plotting
-@subsection Surf3A
+@cindex Surf3C
 @cindex Surf3A
+@cindex TileS
+@cindex Map
+@cindex STFA
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}stl)
-Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично Surf3(), но прозрачность задается массивом @var{c}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Все размеры массивов @var{z} и @var{c} должны быть одинаковы. Массивы @var{x}, @var{y}, @var{z} могут быть векторами (не 3d массивами как @var{a}). Замечу, что возможно некорректная отрисовка граней вследствие неопределенности построения сечения если поверхность пересекает ячейку данных 2 и более раз. См. также @ref{Surf3}, @ref{SurfA}, @ref{Surf3C}. @sref{Surf3A sample}
-@end deftypefn
+Эти функции строят графики для двух связанных массивов. Есть несколько основных типов 3D графиков: поверхность и поверхность уровня с окраской по второму массиву (SurfC, Surf3C), поверхность и поверхность уровня с прозрачностью по второму массиву (SurfA, Surf3A), плитки переменного размера (TileS), диаграмма точечного отображения (Map), STFA диаграмма (STFA). По умолчанию (если отсутствуют) значения @var{x}, @var{y} (и @var{z} для @code{Surf3C, Surf3A}) равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} или @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Массивы @var{x}, @var{y} (и @var{z} для @code{Surf3C, Surf3A}) могут быть векторами (не матрицами как @var{a}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}).
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{float} val, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_surf3a_val (@code{HMGL} gr, @code{float} val, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+
+@anchor{surfc}
+@deftypefn {Команда MGL} {} surfc zdat cdat ['sch'='']
+@deftypefnx {Команда MGL} {} surfc xdat ydat zdat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surfc (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surfc_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. График строится для каждого z среза данных. См. также @ref{surf}, @ref{surfa}, @ref{surf3c}. @sref{SurfC sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}stl=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}stl, @code{int} num)
-Рисует @var{num} поверхностей уровня равномерно распределенных в интервале [@var{Cmin}, @var{Cmax}].
+@anchor{surf3c}
+@deftypefn {Команда MGL} {} surf3c adat cdat @code{val} ['sch'='']
+@deftypefnx {Команда MGL} {} surf3c xdat ydat zdat adat cdat @code{val} ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{float} val, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3c_val (@code{HMGL} gr, @code{float} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz_val (@code{HMGL} gr, @code{float} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично @ref{surf3}, но цвет задается массивом @var{c}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. См. также @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3C sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{int} num=@code{3})
-@deftypefnx {Функция С} @code{void} mgl_surf3a (@code{HMGL} gr, @code{const HMDT} a, @code{const HMDT} c, @code{const char *}sch, @code{int} num)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@deftypefn {Команда MGL} {} surf3c adat cdat ['sch'='']
+@deftypefnx {Команда MGL} {} surf3c xdat ydat zdat adat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3c (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @var{value} в опциях @var{opt} (по умолчанию 3).
 @end deftypefn
 
-@c ==================================================================
-@node TileS, Map, Surf3A, Dual plotting
-@subsection TileS
-@cindex TileS
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_tiles_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} r, @code{const char *}sch)
-Рисует плитки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Аналогично Tile(), но размер плиток задается массивов @var{r}. Это создает эффект "прозрачности" при экспорте в файлы EPS. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=z.nx && y.nx=z.ny} или @code{x.nx=y.nx=z.nx && x.ny=y.ny=z.ny}. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{z}). График строится для каждого z среза данных. См. также @ref{SurfA}, @ref{Tile}. @sref{TileS sample}
+@anchor{surfa}
+@deftypefn {Команда MGL} {} surfa zdat cdat ['sch'='']
+@deftypefnx {Команда MGL} {} surfa xdat ydat zdat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surfa (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с прозрачностью, заданной массивом @var{c}[i,j]. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. График строится для каждого z среза данных. См. также @ref{surf}, @ref{surfc}, @ref{surf3a}. @sref{SurfA sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_tiles (@code{HMGL} gr, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
+@anchor{surf3a}
+@deftypefn {Команда MGL} {} surf3a adat cdat @code{val} ['sch'='']
+@deftypefnx {Команда MGL} {} surf3a xdat ydat zdat adat cdat @code{val} ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{float} val, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{float} val, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3a_val (@code{HMGL} gr, @code{float} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz_val (@code{HMGL} gr, @code{float} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично @ref{surf3}, но прозрачность задается массивом @var{c}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. См. также @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3A sample}
 @end deftypefn
 
-@c ==================================================================
-@node Map, STFA, TileS, Dual plotting
-@subsection Map
-@cindex Map
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{int} ks=@code{0}, @code{bool} pnts=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_map_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{int} ks, @code{int} pnts)
-Визуализирует точечное отображение для матриц @{@var{ax}, @var{ay} @} параметрически зависящих от координат @var{x}, @var{y}. Исходное положение ячейки задает ее цвет. Высота пропорциональна якобиану J(ax,ay). График является аналогом диаграммы Арнольда. Если @code{pnts=false}, то рисуются грани, иначе цветные точки рисуются в узлах матриц (полезно для "запутанного" отображения). Параметр @var{ks} задает используемый срез матриц. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). @xref{Color scheme}. @sref{Map sample}
+@deftypefn {Команда MGL} {} surf3a adat cdat ['sch'='']
+@deftypefnx {Команда MGL} {} surf3a xdat ydat zdat adat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_surf3a (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @var{value} в опциях @var{opt} (по умолчанию 3).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{int} ks=@code{0}, @code{bool} pnts=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_map (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{int} ks, @code{int} pnts)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
+@anchor{tiles}
+@deftypefn {Команда MGL} {} tiles zdat rdat ['sch'='']
+@deftypefnx {Команда MGL} {} tiles xdat ydat zdat rdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}r, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tiles (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tiles_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует плитки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Аналогично Tile(), но размер плиток задается массивов @var{r}. Это создает эффект "прозрачности" при экспорте в файлы EPS. График строится для каждого z среза данных. См. также @ref{surfa}, @ref{tile}. @sref{TileS sample}
 @end deftypefn
 
-@c ==================================================================
-@node STFA, , Map, Dual plotting
-@subsection STFA
-@cindex STFA
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}re, @code{const mglData &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} re, @code{const HMDT} im, @code{int} dn, @code{const char *}sch, @code{float} zVal)
-Рисует спектрограмму комплексного массива @var{re}+i*@code{im} для Фурье размером @var{dn} точек в плоскости @var{z=zVal}. Параметр @var{dn} -- любое четное число. Например в 1D случае, результатом будет график плотности от массива @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} размером @{int(nx/dn), dn, ny@}. Массивы @var{re}, @var{im} параметрически зависят от координат @var{x}, @var{y}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Все размеры массивов @var{re} и @var{im} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{re} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{re}).  @sref{STFA sample}
+@anchor{map}
+@deftypefn {Команда MGL} {} map udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} map xdat ydat udat vdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_map (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_map_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует точечное отображение для матриц @{@var{ax}, @var{ay} @} параметрически зависящих от координат @var{x}, @var{y}. Исходное положение ячейки задает ее цвет. Высота пропорциональна якобиану J(ax,ay). График является аналогом диаграммы Арнольда. Если @var{sch} содержит @samp{.}, то цветные точки рисуются в узлах матриц (полезно для "запутанного" отображения), иначе рисуются грани. @sref{Mapping visualization}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglData &}re, @code{const mglData &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_stfa (@code{HMGL} gr, @code{const HMDT} re, @code{const HMDT} im, @code{int} dn, @code{const char *}sch, @code{float} zVal)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
+@anchor{stfa}
+@deftypefn {Команда MGL} {} stfa re im @code{dn} ['sch'='']
+@deftypefnx {Команда MGL} {} stfa xdat ydat re im @code{dn} ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglData &}re, @code{const mglData &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}re, @code{const mglData &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует спектрограмму комплексного массива @var{re}+i*@var{im} для Фурье размером @var{dn} точек в плоскости @var{z}=@var{Min}.z. Параметр @var{dn} -- любое чётное число. Например в 1D случае, результатом будет график плотности от массива @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} размером @{int(nx/dn), dn, ny@}. Массивы @var{re}, @var{im} параметрически зависят от координат @var{x}, @var{y}. Все размеры массивов @var{re} и @var{im} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{re} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{re}). @sref{STFA sample}
 @end deftypefn
 
 
 @c ##################################################################
 @node Vector fields, Other plotting, Dual plotting, MathGL core
 @section Векторные поля
-
-Эти функции рисуют графики для 2D и 3D векторных полей. Есть несколько типов графиков: просто векторное поле (Vect), вектора вдоль траектории (Traj), векторное поле каплями (Dew), нити тока (Flow, FlowP), трубки тока (Pipe). Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой @xref{Color scheme}.
-
-@menu
-* Traj::
-* Vect::
-* Dew::
-* Flow::
-* FlowP::
-* Pipe::
-@end menu
-
-@c ==================================================================
-@subsection Grad
-@cindex Grad
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}phi, @code{const char *}sch=@code{""}, @code{int} num=@code{5})
-@deftypefnx {Функция С} @code{void} mgl_grad_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch, @code{int} num, @code{float} zVal)
-Рисует линии градиента скалярного поля @var{phi}[i,j,k] заданного параметрически @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Число линий пропорционально @var{num}. Линии рисуются только с границ интервала при @var{num}<0. Младшие размерности массивов @var{x}, @var{y}, @var{z}, @var{phi} должны быть одинаковы @code{x.nx=phi.nx && y.nx=phi.ny && z.nx=phi.nz} или @code{x.nx=y.nx=z.nx=phi.nx && x.ny=y.ny=z.ny=phi.ny && x.nz=y.nz=z.nz=phi.nz}. Массивы @var{x}, @var{y} и @var{z} могут быть векторами (не матрицами как @var{phi}). См. также @ref{Dens3}, @ref{Cont3}, @ref{Flow}.
-@end deftypefn
-
-
-@c ==================================================================
-@node Traj, Vect, , Vector fields
-@subsection Traj
 @cindex Traj
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{float} len=@code{0})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN}, @code{float} len=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_traj_xyz (@code{HMGL} gr, @code{const HMDT}x, @code{const HMDT}y, @code{const HMDT}z, @code{const HMDT}ax, @code{const HMDT}ay, @code{const HMDT}az, @code{const char *}sch, @code{float} len)
-@deftypefnx {Функция С} @code{void} mgl_traj_xy (@code{HMGL} gr, @code{const HMDT}x, @code{const HMDT}y, @code{const HMDT}ax, @code{const HMDT}ay, @code{const char *}sch, @code{float} zVal, @code{float} len)
-Рисует вектора @{@var{ax}, @var{ay}, @var{az}@} вдоль кривой @{@var{x}, @var{y}, @var{z}@}. Длина векторов пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}. Строка @var{pen} задает цвет (см. @ref{Line styles}). По умолчанию (@code{pen=""}) используется текущий цвет из палитры (см. @ref{Palette and colors}). Параметр @var{len} задает фактор длины векторов (если не нуль) или выбирать длину пропорционально расстоянию между точками кривой (если @var{len}=0). Размер по 1-му индексу должен быть 2 или больше. График рисуется для каждой строки если один из массивов матрица. См. также @ref{Vect}. @sref{Traj sample}
-@end deftypefn
-
-@c ==================================================================
-@node Vect, Dew, Traj, Vector fields
-@subsection Vect
 @cindex Vect
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN}, @code{int} flag=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} zVal, @code{int} flag)
-Рисует векторное поле @{@var{ax}, @var{ay}@} параметрически зависящее от координат @var{x}, @var{y} на плоскости при @var{z}=@var{zVal}. Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2@}}. Число рисуемых векторов зависит от @ref{MeshNum}. Цвет задается строкой @var{sch}. Предыдущая цветовая схема используется по умолчанию. Параметр @var{flag} побитовый флаг для настройки вид векторов: @code{MGL_VEC_COL} -- двуцветный вектор, @code{MGL_VEC_LEN} -- одинаковая длина векторов, @code{MGL_VEC_DOT} -- рисует штрихи вместо стрелок, @code{MGL_VEC_END} -- рисует стрелку в точку сетки, @code{MGL_VEC_MID} -- рисует стрелку с серединой в точке сетки. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y} и @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). График строится для каждого z среза @var{ax}, @var{ay}. См. также @ref{Flow}, @ref{Dew}. @sref{Vect sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN}, @code{int} flag=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} zVal, @code{int} flag)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{int} flag=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_vect_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{int} flag)
-Это 3D версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны быть 3d массивами, а длина и цвет пропорциональны @math{\sqrt@{ax^2+ay^2+az^2@}}. @sref{Vect 3D sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{int} flag=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_vect_3d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{int} flag)
-Как предыдущий с @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node Dew, Flow, Vect, Vector fields
-@subsection Dew
 @cindex Dew
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} zVal)
-Рисует капли для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} при @var{z=zVal}. Замечу, что график требует много памяти и процессорного времени для своего создания! Цвет капель пропорционален @math{\sqrt@{ax^2+ay^2@}}. Число капель определяется @ref{MeshNum}. Цвет задается строкой @var{sch}. Предыдущая цветовая схема используется по умолчанию. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y} и @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). График строится для каждого z среза @var{ax}, @var{ay}. См. также @ref{Vect}. @sref{Dew sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_dew (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} zVal)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node Flow, FlowP, Dew, Vector fields
-@subsection Flow
 @cindex Flow
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{int} num=@code{5}, @code{bool} central=@code{true}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{int} num, @code{int} central, @code{float} zVal)
-Рисует нити тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при z = @var{zVal}. Число нитей пропорционально @var{num}. Параметр @var{central} задает возможность старта нитей изнутри сетки (если true) или только с краев (если false). С версии 1.11 он игнорируется и всегда равен (@var{num}>0). Цвет нитей пропорционален @math{\sqrt@{ax^2+ay^2@}}. Теплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y} и @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). График строится для каждого z среза @var{ax}, @var{ay}. См. также @ref{Pipe}, @ref{Vect}. @sref{Flow sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{int} num=@code{5}, @code{bool} central=@code{true}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{int} num, @code{int} central, @code{float} zVal)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{int} num=@code{3}, @code{bool} central=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_flow_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{int} num, @code{int} central)
-Это 3D версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны быть 3d массивами, а цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}. @sref{Flow 3D sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{int} num=@code{3}, @code{bool} central=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_flow_3d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{int} num, @code{int} central)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@c ==================================================================
-@node FlowP, Pipe, Flow, Vector fields
-@subsection FlowP
 @cindex FlowP
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph} (Python)} @code{void} FlowP (@code{float} x0, @code{float} y0, @code{float} z0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_flowp_xy (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch)
-Рисует нить тока из точки @var{p0} для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при z = @var{p0}.z. Цвет нити пропорционален @math{\sqrt@{ax^2+ay^2@}}. Теплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y} и @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). График строится для каждого z среза @var{ax}, @var{ay}. См. также @ref{Pipe}, @ref{Vect}.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph} (Python)} @code{void} FlowP (@code{float} x0, @code{float} y0, @code{float} z0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_flowp_2d (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph} (Python)} @code{void} FlowP (@code{float} x0, @code{float} y0, @code{float} z0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_flowp_xyz (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch)
-Это 3D версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны быть 3d массивами, а цвет пропорциональны @math{\sqrt@{ax^2+ay^2+az^2@}}. @sref{Flow 3D sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph} (Python)} @code{void} FlowP (@code{float} x0, @code{float} y0, @code{float} z0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_flowp_3d (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-
-@c ==================================================================
-@node Pipe, , FlowP, Vector fields
-@subsection Pipe
 @cindex Pipe
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{int} num=@code{5}, @code{bool} central=@code{true}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} r0, @code{int} num, @code{int} central, @code{float} zVal)
-Рисует трубки тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при z = @var{zVal}. Число трубок пропорционально @var{num}. Параметр @var{central} задает возможность старта трубок изнутри сетки (если true) или только с краев (если false). С версии 1.11 он игнорируется и всегда равен (@var{num}>0). Цвет и радиус трубок пропорционален @math{\sqrt@{ax^2+ay^2@}}. Теплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Параметр @var{r0} задает радиус трубок. При @var{r0}<0 радиус трубок обратно пропорционален их амплитуде. Все размеры массивов @var{ax} и @var{ay} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y} и @var{ax} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{ax}). График строится для каждого z среза @var{ax}, @var{ay}. См. также @ref{Flow}, @ref{Vect}. @sref{Pipe sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{int} num=@code{5}, @code{bool} central=@code{true}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const char *}sch, @code{float} r0, @code{int} num, @code{int} central, @code{float} zVal)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{int} num=@code{3}, @code{bool} central=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_pipe_xyz (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{float} r0, @code{int} num, @code{int} central)
-Это 3D версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны быть 3d массивами, а цвет пропорциональны @math{\sqrt@{ax^2+ay^2+az^2@}}. @sref{Pipe 3D sample}
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{int} num=@code{3}, @code{bool} central=@code{true})
-@deftypefnx {Функция С} @code{void} mgl_pipe_3d (@code{HMGL} gr, @code{const HMDT} ax, @code{const HMDT} ay, @code{const HMDT} az, @code{const char *}sch, @code{float} r0, @code{int} num, @code{int} central)
-Как предыдущий с @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
-
-
-@c ##################################################################
-@node Other plotting, Nonlinear fitting, Vector fields, MathGL core
-@section Прочие графики
-
-Это функции, не относящиеся к какой-то специальной категории. Сюда входят функции построения графиков по текстовым формулам (Plots by formula), рисования поверхностей из треугольников (TriPlot), произвольных точек в пространстве (Dots) и реконструкции по ним поверхности (Crust), графики плотности и линии уровня на плоскостях, перпендикулярных осям x, y или z (Dens[XYZ], Cont[XYZ], ContF[XYZ]), функция "упрощенного" рисования (SimplePlot). Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой. @xref{Color scheme}.
-
-@menu
-* DensXYZ::
-* ContXYZ::
-* ContFXYZ::
-* Dots::
-* Crust::
-* TriPlot::
-* TriCont::
-* QuadPlot::
-* Plots by formula::
-* SimplePlot::
-@end menu
-
-@c ==================================================================
-@node DensXYZ, ContXYZ, , Other plotting
-@subsection DensXYZ
-@cindex DensX
-@cindex DensY
-@cindex DensZ
-
-Эти функции рисуют график плотности на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. Например, код
-@example
-gr->DensX(c.Sum("x"),"BbcyrR",-1);
-gr->DensY(c.Sum("y"),0,1);
-gr->DensZ(c.Sum("z"),0,-1);
-@end example
-создают такую картинку. См. также @ref{ContXYZ}, @ref{ContFXYZ}, @ref{Dens}, @ref{Data distributions}. @sref{Dens projection sample}
+Эти функции рисуют графики для 2D и 3D векторных полей. Есть несколько типов графиков: просто векторное поле (Vect), вектора вдоль траектории (Traj), векторное поле каплями (Dew), нити тока (Flow, FlowP), трубки тока (Pipe). По умолчанию (если отсутствуют) значения @var{x}, @var{y} и @var{z} равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} и @var{ax} должны быть одинаковы. Размеры массивов @var{ax}, @var{ay} и @var{az} должны быть одинаковы. Массивы @var{x}, @var{y} и @var{z} могут быть векторами (не матрицами как @var{ax}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}).
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} DensX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_dens_x (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует график плотности @var{a} при x = @var{sVal}.
-@end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} DensY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_dens_y (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует график плотности @var{a} при y = @var{sVal}.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} DensZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_dens_z (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует график плотности @var{a} при z = @var{sVal}.
-@end deftypefn
-
-@c ==================================================================
-@node ContXYZ, ContFXYZ, DensXYZ, Other plotting
-@subsection ContXYZ
-@cindex ContX
-@cindex ContY
-@cindex ContZ
-
-Эти функции рисуют линии уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. Например, код
-@example
-gr->ContX(c.Sum("x"),"BbcyrR",-1);
-gr->ContY(c.Sum("y"),0,1);
-gr->ContZ(c.Sum("z"),0,-1);
-@end example
-создают такую картинку. См. также @ref{ContFXYZ}, @ref{DensXYZ}, @ref{Cont}, @ref{Data distributions}. @sref{Cont projection sample}
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont_x (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} линий уровня для массива @var{a} при x = @var{sVal}.
+@anchor{traj}
+@deftypefn {Команда MGL} {} traj xdat ydat udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} traj xdat ydat zdat udat vdat wdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_traj_xyz (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}z, @code{HCDT}ax, @code{HCDT}ay, @code{HCDT}az, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_traj_xy (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}ax, @code{HCDT}ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует вектора @{@var{ax}, @var{ay}, @var{az}@} вдоль кривой @{@var{x}, @var{y}, @var{z}@}. Длина векторов пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}. Строка @var{pen} задает цвет (см. @ref{Line styles}). По умолчанию (@code{pen=""}) используется текущий цвет из палитры (см. @ref{Palette and colors}). Опция @var{value} задает фактор длины векторов (если не нуль) или выбирать длину пропорционально расстоянию между точками кривой (если @var{value}=0). Размер по 1-му индексу должен быть 2 или больше. График рисуется для каждой строки если один из массивов матрица. См. также @ref{vect}. @sref{Traj sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont_y (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} линий уровня для массива @var{a} при y = @var{sVal}.
+@anchor{vect}
+@deftypefn {Команда MGL} {} vect udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} vect xdat ydat udat vdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует векторное поле @{@var{ax}, @var{ay}@} параметрически зависящее от координат @var{x}, @var{y} на плоскости при @var{z}=@var{Min}.z. Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2@}}. Число рисуемых векторов зависит от @ref{meshnum}. Вид стрелок/штрихов может быть изменён символами:
+@itemize @bullet
+@item
+@samp{f} для стрелок одинаковой длины,
+@item
+@samp{>}, @samp{<} для стрелок начинающихся или заканчивающихся в ячейке сетки (по умолчанию центрированы),
+@item
+@samp{.} для рисования штрихов с точкой в начале вместо стрелок,
+@item
+@samp{=} для использования градиента цвета вдоль стрелок.
+@end itemize
+См. также @ref{flow}, @ref{dew}. @sref{Vect sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_cont_z (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} линий уровня для массива @var{a} при z = @var{sVal}.
+@deftypefn {Команда MGL} {} vect udat vdat wdat ['sch'='']
+@deftypefnx {Команда MGL} {} vect xdat ydat zdat udat vdat wdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_vect_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_vect_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Это 3d версия графика. Здесь массивы должны трёхмерными тензорами и длина вектора пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_cont_x_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует линии уровня для массива  @var{a}=@var{v}[i] при x = @var{sVal}.
+@anchor{dew}
+@deftypefn {Команда MGL} {} dew udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} dew xdat ydat udat vdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_dew (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует капли для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} при @var{z}=@var{Min}.z. Замечу, что график требует много памяти и процессорного времени для своего создания! Цвет капель пропорционален @math{\sqrt@{ax^2+ay^2@}}. Число капель определяется @ref{meshnum}. См. также @ref{vect}. @sref{Dew sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_cont_y_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует линии уровня для массива  @var{a}=@var{v}[i] при y = @var{sVal}.
+@anchor{flow}
+@deftypefn {Команда MGL} {} flow udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} flow xdat ydat udat vdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует нити тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} = @var{Min}.z. Число нитей пропорционально значению опции @var{value} (по умолчанию 5). Цвет нитей пропорционален @math{\sqrt@{ax^2+ay^2@}}. Строка @var{sch} может содержать
+@itemize @bullet
+@item
+цветовую схему -- тёплые цвета соответствуют нормальному току (типа стока), холодные цвета соответствуют обратному току (типа источника);
+@item
+@samp{#} для использования нитей, начинающихся только на границе;
+@item
+@samp{v} для рисования стрелок на нитях;
+@item
+@samp{x}, @samp{z} для рисования лент нормалей, начинающихся в плоскостях x-y и y-z соответственно.
+@end itemize
+См. также @ref{pipe}, @ref{vect}, @ref{tape}, @ref{barwidth}. @sref{Flow sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_cont_z_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует линии уровня для массива  @var{a}=@var{v}[i] при z = @var{sVal}.
+@deftypefn {Команда MGL} {} flow udat vdat wdat ['sch'='']
+@deftypefnx {Команда MGL} {} flow xdat ydat zdat udat vdat wdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_flow_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_flow_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Это 3d версия графика. Здесь массивы должны трёхмерными тензорами и цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}.
 @end deftypefn
 
-@c ==================================================================
-@node ContFXYZ, Dots, ContXYZ, Other plotting
-@subsection ContFXYZ
-@cindex ContFX
-@cindex ContFY
-@cindex ContFZ
-
-Эти функции рисуют закрашенные контуры уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContXYZ}, @ref{DensXYZ}, @ref{ContF}, @ref{Data distributions}.
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf_x (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} закрашенных контуров уровня для массива @var{a} при x = @var{sVal}.
+@deftypefn {Команда MGL} {} flow @code{x0 y0} udat vdat ['sch'='']
+@deftypefnx {Команда MGL} {} flow @code{x0 y0} xdat ydat udat vdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_flowp_2d (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_flowp_xy (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Аналогично @ref{flow}, @var{p0}=@{@var{x0},@var{y0},@var{z0}@}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf_y (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} закрашенных контуров уровня для массива @var{a} при y = @var{sVal}.
+@deftypefn {Команда MGL} {} flow @code{x0 y0 z0} udat vdat wdat ['sch'='']
+@deftypefnx {Команда MGL} {} flow @code{x0 y0 z0} xdat ydat zdat udat vdat wdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_flowp_3d (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_flowp_xyz (@code{HMGL} gr, @code{float} x0, @code{float} y0, @code{float} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Это 3d версия графика. Здесь массивы должны трёхмерными тензорами и цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{int} num=@code{7})
-@deftypefnx {Функция С} @code{void} mgl_contf_z (@code{HMGL} gr, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal, @code{int} num)
-Рисует @var{num} закрашенных контуров уровня для массива @var{a} при z = @var{sVal}.
+@anchor{grad}
+@deftypefn {Команда MGL} {} grad pdat ['sch'='']
+@deftypefnx {Команда MGL} {} grad xdat ydat pdat ['sch'='']
+@deftypefnx {Команда MGL} {} grad xdat ydat zdat pdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglData &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_grad (@code{HMGL} gr, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_grad_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_grad_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует линии градиента скалярного поля @var{phi}[i,j] (или @var{phi}[i,j,k] в 3d случае) заданного параметрически @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Число линий пропорционально значению опции @var{value}. Линии рисуются только с границ интервала при @var{value}<0. См. также @ref{dens}, @ref{cont}, @ref{flow}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_contf_x_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует закрашенные конутры уровня для массива @var{a}=@var{v}[i] при x = @var{sVal}.
+@anchor{pipe}
+@deftypefn {Команда MGL} {} pipe udat vdat ['sch'='' @code{r0=0.05}]
+@deftypefnx {Команда MGL} {} pipe xdat ydat udat vdat ['sch'='' @code{r0=0.05}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}ax, @code{const mglData &}ay, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
+@end ifclear
+Рисует трубки тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} = @var{Min}.z. Число трубок пропорционально значению опции @var{value}. Цвет и радиус трубок пропорционален @math{\sqrt@{ax^2+ay^2@}}. Тёплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Параметр @var{r0} задает радиус трубок. При @var{r0}<0 радиус трубок обратно пропорционален их амплитуде. См. также @ref{flow}, @ref{vect}. @sref{Pipe sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_contf_y_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует закрашенные конутры уровня для массива @var{a}=@var{v}[i] при y = @var{sVal}.
+@deftypefn {Команда MGL} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
+@deftypefnx {Команда MGL} {} pipe xdat ydat zdat udat vdat wdat ['sch'='' @code{r0=0.05}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}ax, @code{const mglData &}ay, @code{const mglData &}az, @code{const char *}sch=@code{""}, @code{float} r0=@code{0.05}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_pipe_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_pipe_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{float} r0, @code{const char *}opt)
+@end ifclear
+Это 3d версия графика. Здесь массивы должны трёхмерными тензорами и цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_contf_z_val (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} a, @code{const char *}stl, @code{float} sVal)
-Рисует закрашенные конутры уровня для массива @var{a}=@var{v}[i] при z = @var{sVal}.
-@end deftypefn
 
-@c ==================================================================
-@node Dots, Crust, ContFXYZ, Other plotting
-@subsection Dots
+@c ##################################################################
+@node Other plotting, Nonlinear fitting, Vector fields, MathGL core
+@section Прочие графики
+@cindex DensXYZ
+@cindex ContXYZ
+@cindex ContFXYZ
 @cindex Dots
+@cindex Crust
+@cindex TriPlot
+@cindex TriCont
+@cindex QuadPlot
+@cindex FPlot
+@cindex FSurf
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dots (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch)
-@deftypefnx {Функция С} @code{void} mgl_dots_a (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}sch)
-Рисует произвольно расположенные точки @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если определен массив @var{a}, то он задает прозрачность точек. Массивы @var{x}, @var{y}, @var{z}, @var{a} должны иметь одинаковые размеры. См. также @ref{Crust}, @ref{Mark}, @ref{Plot}. @sref{Dots sample}
-@end deftypefn
+Это функции, не относящиеся к какой-то специальной категории. Сюда входят функции построения графиков по текстовым формулам (FPlot и FSurf), рисования поверхностей из треугольников и четырёхугольников (TriPlot, TriCont, QuadPlot), произвольных точек в пространстве (Dots) и реконструкции по ним поверхности (Crust), графики плотности и линии уровня на плоскостях, перпендикулярных осям x, y или z (Dens[XYZ], Cont[XYZ], ContF[XYZ]). Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой. @xref{Color scheme}.
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglData &}tr, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_dots_tr (@code{HMGL} gr, @code{const HMDT} tr, @code{const char *}sch)
-Как предыдущий с @var{x=tr}(0,:), @var{y=tr}(1,:), @var{z=tr}(2,:) и если @var{tr}.nx>3, то @var{a=tr}(3,:).
+@anchor{densz} @anchor{densy} @anchor{densx} @anchor{DensXYZ}
+@deftypefn {Команда MGL} {} densx dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} densy dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} densz dat ['sch'='' @code{sval=nan}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_dens_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dens_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dens_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Эти функции рисуют график плотности на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContXYZ}, @ref{ContFXYZ}, @ref{dens}, @ref{Data manipulation}. @sref{Dens projection sample}
 @end deftypefn
 
-@c ==================================================================
-@node Crust, TriPlot, Dots, Other plotting
-@subsection Crust
-@cindex Crust
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Crust (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{float} er=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_crust (@code{HMGL} gr, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch, @code{float} er)
-Реконструирует и рисует поверхность по произвольно расположенным точкам @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Параметр @var{er} задает радиус ошибки (увеличте для удаления дыр). Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. См. также @ref{Dots}, @ref{TriPlot}. @sref{Crust sample}
+@anchor{contz} @anchor{conty} @anchor{contx} @anchor{ContXYZ}
+@deftypefn {Команда MGL} {} contx dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} conty dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} contz dat ['sch'='' @code{sval=nan}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Эти функции рисуют линии уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{Cont projection sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Crust (@code{const mglData &}tr, @code{const char *}sch=@code{""}, @code{float} er=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_crust_tr (@code{HMGL} gr, @code{const HMDT} tr, @code{const char *}sch, @code{float} er)
-Как предыдущий с @var{x=tr}(0,:), @var{y=tr}(1,:), @var{z=tr}(2,:).
+@ifclear UDAV
+@deftypefn {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_cont_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_cont_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+Аналогично предыдущему с ручным заданием значений для линий уровня.
 @end deftypefn
+@end ifclear
 
-@c ==================================================================
-@node TriPlot, TriCont, Crust, Other plotting
-@subsection TriPlot
-@cindex TriPlot
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_triplot_xyz (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch)
-@deftypefnx {Функция С} @code{void} mgl_triplot_xyzc (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Рисует поверхность из треугольников. Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{Dots}, @ref{Crust}, @ref{QuadPlot}, @ref{TriCont}.
+@anchor{contfz} @anchor{contfy} @anchor{contfx} @anchor{ContFXYZ}
+@deftypefn {Команда MGL} {} contfx dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} contfy dat ['sch'='' @code{sval=nan}]
+@deftypefnx {Команда MGL} {} contfz dat ['sch'='' @code{sval=nan}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@end ifclear
+Эти функции рисуют закрашенные контуры уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{ContF projection sample}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_triplot_xy (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const char *}sch, @code{float} zVal)
-Как предыдущий с @var{z}[i]=@var{zVal}.
+@ifclear UDAV
+@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglData &}v, @code{const mglData &}a, @code{const char *}stl=@code{""}, @code{float} sVal=@code{NAN}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_contf_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_contf_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{float} sVal, @code{const char *}opt)
+Аналогично предыдущему с ручным заданием значений для линий уровня.
 @end deftypefn
+@end ifclear
 
-@c ==================================================================
-@node TriCont, QuadPlot, TriPlot, Other plotting
-@subsection TriCont
-@cindex TriCont
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglData &}v, @code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglData &}v, @code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch, @code{float} zVal)
-@deftypefnx {Функция С} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{const HMDT} v, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch, @code{float} zVal)
-Рисует линии уровня поверхности из треугольников при @var{z} = @var{zVal} (или для @var{z=v}[k] если @code{zVal==NAN}). Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{TriPlot}, @ref{Cont}.
+@anchor{fplot}
+@deftypefn {Команда MGL} {} fplot 'y(x)' ['pen'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FPlot (@code{const char *}eqY, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}pen, @code{const char *}opt)
+@end ifclear
+Рисует функцию @samp{eqY(x)} в плоскости @var{z}=@var{Min}.z с координатой @samp{x} в диапазоне [@var{Min}.x, @var{Max}.x]. См. также @ref{plot}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{num}=@code{7}, @code{float} zVal=@code{NAN})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{num}=@code{7}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_tricont_xyzc (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch, @code{num}, @code{float} zVal)
-@deftypefnx {Функция С} @code{void} mgl_tricont_xyz (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch, @code{num}, @code{float} zVal)
-Аналогично предыдущему с вектором @var{v} из @var{num} элементов равно распределенных в интервале [@var{Cmin}, @var{Cmax}].
+@deftypefn {Команда MGL} {} fplot 'x(t)' 'y(t)' 'z(t)' ['pen'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FPlot (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_fplot_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt)
+@end ifclear
+Рисует параметрическую кривую @{@samp{eqX(t)}, @samp{eqY(t)}, @samp{eqZ(t)}@}, где координата @samp{t} меняется в диапазоне [0, 1]. См. также @ref{plot}.
 @end deftypefn
 
-@c ==================================================================
-@node QuadPlot, Plots by formula, TriCont, Other plotting
-@subsection QuadPlot
-@cindex QuadPlot
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""})
-@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_quadplot_xyz (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const char *}sch)
-@deftypefnx {Функция С} @code{void} mgl_quadplot_xyzc (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} c, @code{const char *}sch)
-Рисует поверхность из четырехугольников. Вершины четырехугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Предыдущая цветовая схема используется по умолчанию. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 4 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет четырехугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{TriPlot}.
+@anchor{fsurf}
+@deftypefn {Команда MGL} {} fsurf 'z(x,y)' ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FSurf (@code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""});
+@deftypefnx {Функция С} @code{void} mgl_fsurf (@code{HMGL} gr, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt);
+@end ifclear
+Рисует поверхность @samp{eqY(x,y)} с координатами @samp{x}, @samp{y} в диапазоне [@var{Min}, @var{Max}]. См. также @ref{surf}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const char *}sch=@code{""}, @code{float} zVal=@code{NAN})
-@deftypefnx {Функция С} @code{void} mgl_quadplot_xy (@code{HMGL} gr, @code{const HMDT} id, @code{const HMDT} x, @code{const HMDT} y, @code{const char *}sch, @code{float} zVal)
-Как предыдущий с @var{z}[i]=@var{zVal}.
+@deftypefn {Команда MGL} {} fsurf 'x(u,v)' 'y(u,v)' 'z(u,v)' ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} FSurf (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_fsurf_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует параметрическую поверхность @{@samp{eqX(u,v)}, @samp{eqY(u,v)}, @samp{eqZ(u,v)}@}, где координаты @samp{u}, @samp{v} меняются в диапазоне [0, 1]. См. также @ref{surf}.
 @end deftypefn
 
-@c ==================================================================
-@node Plots by formula, SimplePlot, QuadPlot, Other plotting
-@subsection Графики функций
-@cindex Plot
-@cindex Surf
-
-Эти функции строят графики 1D или 2D функций, заданный текстовыми формулами. Вам не нужно создавать массивы для их построения. Параметр @var{stl} задаект стиль линии (см. @ref{Line styles}) для @code{Plot()} или цветовую схему (см. @ref{Color scheme}) для @code{Surf()}. Параметр @var{n} задает минимальное число точек по координате(ам) для графика. В настоящее время (v. 1.10) число точек автоматически увеличивается для области резкого изменения функции, но только для 1D графиков (т.е. для Plot()).
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Plot (@code{const char *}eqY, @code{const char *}stl=@code{""}, @code{float} zVal=@code{NAN}, @code{int} n=@code{100})
-@deftypefnx {Функция С} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}stl, @code{float} zVal, @code{int} n)
-Рисует функцию @samp{eqY(x)} в плоскости z=@var{zVal} с координатой @samp{x} в диапазоне [@var{Min}.x, @var{Max}.x]. См. также @ref{Plot}.
+@anchor{triplot}
+@deftypefn {Команда MGL} {} triplot idat xdat ydat ['sch'='']
+@deftypefnx {Команда MGL} {} triplot idat xdat ydat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} triplot idat xdat ydat zdat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_triplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_triplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_triplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует поверхность из треугольников. Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{dots}, @ref{crust}, @ref{quadplot}. @sref{TriPlot and QuadPlot}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Plot (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}stl=@code{""}, @code{float} zVal=@code{NAN}, @code{int} n=@code{100})
-@deftypefnx {Функция С} @code{void} mgl_fplot_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}stl, @code{float} zVal, @code{int} n)
-Рисует параметрическую кривую @{@samp{eqX(t)}, @samp{eqY(t)}, @samp{eqZ(t)}@}, где координата @samp{t} меняется в диапазоне [0, 1]. См. также @ref{Plot}.
+@anchor{tricont}
+@deftypefn {Команда MGL} {} tricont vdat idat xdat ydat zdat cdat ['sch'='']
+@deftypefnx {Команда MGL} {} tricont vdat idat xdat ydat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} tricont idat xdat ydat zdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglData &}v, @code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglData &}v, @code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_tricont_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tricont_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует линии уровня поверхности из треугольников при @var{z}=@var{v}[k] (или при @var{z} = @var{Min}.z если @var{sch} содержит @samp{_}). Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}, @ref{cont}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf (@code{const char *}eqZ, @code{const char *}stl=@code{""}, @code{int} n=@code{100});
-@deftypefnx {Функция С} @code{void} mgl_fsurf (@code{HMGL} gr, @code{const char *}eqZ, @code{const char *}stl, @code{int} n);
-Рисует поверхность @samp{eqY(x,y)} с координатами @samp{x}, @samp{y} в диапазоне [@var{Min}, @var{Max}]. См. также @ref{Surf}.
+@anchor{quadplot}
+@deftypefn {Команда MGL} {} quadplot idat xdat ydat ['sch'='']
+@deftypefnx {Команда MGL} {} quadplot idat xdat ydat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} quadplot idat xdat ydat zdat cdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglData &}id, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_quadplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_quadplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_quadplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует поверхность из четырёхугольников. Вершины четырёхугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 4 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет четырёхугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}. @sref{TriPlot and QuadPlot}
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Surf (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}stl=@code{""}, @code{int} n=@code{100})
-@deftypefnx {Функция С} @code{void} mgl_fsurf_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}stl, @code{int} n)
-Рисует параметрическую поверхность @{@samp{eqX(u,v)}, @samp{eqY(u,v)}, @samp{eqZ(u,v)}@}, где координаты @samp{u}, @samp{v} меняются в диапазоне [0, 1]. См. также @ref{Surf}.
+@anchor{dots}
+@deftypefn {Команда MGL} {} dots xdat ydat zdat ['sch'='']
+@deftypefnx {Команда MGL} {} dots xdat ydat zdat adat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_dots (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@deftypefnx {Функция С} @code{void} mgl_dots_a (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Рисует произвольно расположенные точки @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Если определён массив @var{a}, то он задает прозрачность точек. Массивы @var{x}, @var{y}, @var{z}, @var{a} должны иметь одинаковые размеры. См. также @ref{crust}, @ref{mark}, @ref{plot}. @sref{Dots sample}
 @end deftypefn
 
-@c ==================================================================
-@node SimplePlot, , Plots by formula, Other plotting
-@subsection SimplePlot
-@cindex SimplePlot
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} SimplePlot (@code{const mglData &}a, @code{int} type=@code{0}, @code{const char *}stl=@code{""})
-@deftypefnx {Функция С} @code{void} mgl_simple_plot (@code{HMGL} gr, @code{const HMDT} a, @code{int} type, @code{const char *}stl)
-Рисует график массива @var{a} в зависимости от его размерности и параметра @var{type}. Строка @var{stl} задает стиль графика. Для 1d массивов: @code{type=0} -- @ref{Plot}, @code{type=1} -- @ref{Area}, @code{type=2} -- @ref{Step}, @code{type=3} -- @ref{Stem}, @code{type=4} -- @ref{Bars}. Для 2d массивов: @code{type=0} -- @ref{Surf}, @code{type=1} -- @ref{Dens}, @code{type=2} -- @ref{Mesh}, @code{type=3} -- @ref{Cont}. Для 3d массивов: @code{type=0} -- @ref{Surf3}, @code{type=1} -- @ref{Dens3}, @code{type=2} -- @ref{Cont3}, @code{type=2} -- @ref{Cloud}.
+@anchor{crust}
+@deftypefn {Команда MGL} {} crust xdat ydat zdat ['sch'='']
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Crust (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_crust (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
+@end ifclear
+Реконструирует и рисует поверхность по произвольно расположенным точкам @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Опция @var{value} задает радиус ошибки (увеличите для удаления дыр). Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. См. также @ref{dots}, @ref{triplot}. @c @sref{Crust sample}
 @end deftypefn
 
 @c ##################################################################
-@node Nonlinear fitting, Data distributions, Other plotting, MathGL core
+@node Nonlinear fitting, Data manipulation, Other plotting, MathGL core
 @section Nonlinear fitting
 @cindex Fit
 @cindex FitS
 @cindex PutsFit
-@cindex FitPnts
+@cindex mglFitPnts
 @cindex Fit2
 @cindex Fit3
 
 Эти функции подбирают параметры функции для наилучшей аппроксимации данных, т.е. минимизируют сумму @math{\sum_i (f(x_i, y_i, z_i) - a_i)^2/s_i^2}. При этом аппроксимирующая функция @samp{f} может зависеть от одного аргумента @samp{x} (1D случай), от двух аргументов @samp{x,y} (2D случай) или от трех аргументов @samp{x,y,z} (3D случай). Функция @samp{f} также может зависеть от параметров. Список параметров задается строкой @var{var} (например, @samp{abcd}). Обычно пользователь должен предоставить начальные значения параметров в переменной @var{ini}. Однако, при его отсутствии используются нулевые значения. Параметр @var{print}=@code{true} включает вывод найденной формулы в @var{Message} (см. @ref{Error handling}).
 
-Функции Fit() и FitS() не рисуют полученные массивы. Они заполняют массив @var{fit} по формуле @samp{f} с найденными коэффициентами и возвращают @math{\chi^2} ошибку аппроксимации. При этом, координаты @samp{x,y,z} равнораспределены в интервале @var{Min}--@var{Max}. Число точек в @var{fit} выбирается максимальным из размера массива @var{fit} и значения переменной @var{FitPnts}. Функции используют библиотеку GSL. @sref{Fitting sample}
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xyzas (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xyzas_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]).
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xyzs (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xyzs_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x- и y-направлений для 2d массива заданного параметрически @var{a}[i,j](@var{x}[i,j], @var{y}[i,j]) для каждого среза данных.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xys (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xys_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-направления для 1d массива заданного параметрически @var{a}[i](@var{x}[i]) для каждого среза данных.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} FitS (@code{mglData &}fit, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_ys (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_ys_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const HMDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-направления для 1d массива с @var{x} равно распределенным в интервале [@var{Min}.x, @var{Max}.x].
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xyza (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xyza_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) с @var{s}[i,j,k]=1.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xyz (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xyz_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x- и y-направлений для 2d массива заданного параметрически @var{a}[i,j](@var{x}[i,j], @var{y}[i,j]) с @var{s}[i,j]=1 для каждого среза данных.
-@end deftypefn
+Функции Fit() и FitS() не рисуют полученные массивы. Они заполняют массив @var{fit} по формуле @samp{f} с найденными коэффициентами и возвращают @math{\chi^2} ошибку аппроксимации. При этом, координаты @samp{x,y,z} равно распределены в интервале @var{Min}--@var{Max}. Число точек в @var{fit} выбирается максимальным из размера массива @var{fit} и значения переменной @var{mglFitPnts}. Функции используют библиотеку GSL. @sref{Nonlinear fitting sample}
 
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}x, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_xy (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_xy_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} x, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-направления для 1d массива заданного параметрически @var{a}[i](@var{x}[i]) с @var{s}[i]=1 для каждого среза данных.
+@anchor{fits}
+@deftypefn {Команда MGL} {} fits res adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fits res xdat adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fits res xdat ydat adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fits res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const mglData &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_ys (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xys (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyzs (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyzas (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@end ifclear
+"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) с весовым множителем @var{s}[i,j,k].
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{""}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_1 (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_1_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-направления для 1d массива @var{a} с @var{s}=1 и @var{x} равно распределенным в интервале [@var{Min}.x, @var{Max}.x].
+@anchor{fit}
+@deftypefn {Команда MGL} {} fit res adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat ydat adat sdat 'func' 'var' [ini=0]
+@deftypefnx {Команда MGL} {} fit res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyza (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@end ifclear
+"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) с весовым множителем 1.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit2 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit2 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_2 (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_2_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x- и y-направлений для 2d массива @var{a} с @var{s}=1 и @var{x}, @var{y} равно распределенными в интервале [@var{Min}, @var{Max}].
-@end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{float} Fit3 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{float *}ini=@code{NULL}, @code{bool} print=@code{false})
-@deftypefnx {Метод класса @code{mglGraph}} @code{float} Fit3 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{bool} print=@code{false})
-@deftypefnx {Функция С} @code{float} mgl_fit_3 (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{float *}ini)
-@deftypefnx {Функция С} @code{float} mgl_fit_3_d (@code{HMGL} gr, @code{HMDT} fit, @code{const HMDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini)
-"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива @var{a} с @var{s}=1 и @var{x}, @var{y}, @var{z} равно распределенными в интервале [@var{Min}, @var{Max}].
+@ifclear UDAV
+@deftypefn {Метод класса @code{mglGraph}} @code{mglData} Fit2 (@code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit2 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglData &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_2 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_fit_3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
+"Подгоняют" формулу вдоль всех направлений для 2d или 3d массива @var{a} с @var{s}=1 и @var{x}, @var{y}, @var{z} равно распределёнными в диапазоне осей координат.
 @end deftypefn
+@end ifclear
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} PutsFit (@code{mglPoint} p, @code{const char *}prefix=@code{""}, @code{const char *}font=@code{NULL}, @code{float} size=@code{-1})
-@deftypefnx {Функция С} @code{void} mgl_puts_fit (@code{HMGL} gr, @code{float} x, @code{float} y, @code{float} z, @code{const char *}prefix, @code{const char *}font, @code{float} size=@code{-1})
+@anchor{putsfit}
+@deftypefn {Команда MGL} {} putsfit @code{x y} ['pre'='' 'fnt'='' @code{size=-1}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} PutsFit (@code{mglPoint} p, @code{const char *}prefix=@code{""}, @code{const char *}font=@code{""}, @code{float} size=@code{-1})
+@deftypefnx {Функция С} @code{void} mgl_puts_fit (@code{HMGL} gr, @code{float} x, @code{float} y, @code{float} z, @code{const char *}prefix, @code{const char *}font, @code{float} size)
+@end ifclear
 Печатает последнюю подобранную формулу с найденными коэффициентами в точке @var{p0}. Строка @var{prefix} будет напечатана перед формулой. Все другие параметры такие же как в @ref{Text printing}.
 @end deftypefn
 
+@ifclear UDAV
 @deftypefn {Метод класса @code{mglGraph}} @code{const char *}GetFit ()
 @deftypefnx {Функция С} @code{const char *} mgl_get_fit (@code{HMGL} gr)
 Возвращает последнюю подобранную формулу с найденными коэффициентами.
 @end deftypefn
+@end ifclear
 
-@deftypecv {Переменная(C++)} mglGraph @code{int} FitPnts
+@deftypevr {Переменная(C++)} @code{int} mglFitPnts
 Минимальное число точек для массива со значениями подобранной формулы.
-@end deftypecv
+@end deftypevr
 
 
 
 
 @c ##################################################################
-@node Data distributions, IDTF functions, Nonlinear fitting, MathGL core
+@node Data manipulation, IDTF functions, Nonlinear fitting, MathGL core
 @section Распределение данных
 @cindex Hist
 
-Эти функции создают распределения данных. Они не выполняют построение сами по себе. Функции могут быть полезны в случае когда данные пользователя определены на случайно расположенных точка (например, после PIC расчетов) и он хочет построить график, требующий регулярных данных (данных на сетках). Диапазон сеток равен диапазону осей координат Min...Max. Массивы @var{x}, @var{y}, @var{z} определяют положение (координаты) точек. Массив @var{a} задает значения данных. Число точек в результате @var{res} -- максимум из размера @var{res} и значения @var{FitPnts}.
-
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Hist (@code{mglData &}res, @code{const mglData &}x, @code{const mglData &}a)
-@deftypefnx {Функция С} @code{int} mgl_hist_x (@code{HMGL} gr, @code{HMDT} res, @code{const HMDT} x, @code{const HMDT} a)
-Создет 1D распределение значений массива @var{a} в диапазоне [Min, Max].
+@deftypefn {Команда MGL} {} hist @sc{res} xdat adat
+@deftypefnx {Команда MGL} {} hist @sc{res} xdat ydat adat
+@deftypefnx {Команда MGL} {} hist @sc{res} xdat ydat zdat adat
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglData &}x, @code{const mglData &}a, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{HMDT} mgl_hist_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_hist_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}opt)
+@deftypefnx {Функция С} @code{HMDT} mgl_hist_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}opt)
+@end ifclear
+Эти функции создают распределения данных. Они не рисуют данные. Функции могут быть полезны в случае когда данные пользователя определены на случайно расположенных точка (например, после PIC расчетов) и он хочет построить график, требующий регулярных данных (данных на сетках). Диапазон сеток равен диапазону осей координат. Массивы @var{x}, @var{y}, @var{z} определяют положение (координаты) точек. Массив @var{a} задает значения данных. Число точек в результате @var{res} -- максимум из размера @var{res} и значения @var{mglFitPnts}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Hist (@code{mglData &}res, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}a)
-@deftypefnx {Функция С} @code{int} mgl_hist_xy (@code{HMGL} gr, @code{HMDT} res, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} a)
-Создет 2D распределение значений массива @var{a} в диапазоне [Min, Max].
+
+@deftypefn {Команда MGL} {} fill dat 'eq'
+@deftypefnx {Команда MGL} {} fill dat 'eq' vdat
+@deftypefnx {Команда MGL} {} fill dat 'eq' vdat wdat
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglData &}v, @code{const char *}opt=@code{""})
+@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglData &}v, @code{const mglData &}w, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} u, @code{const char *}eq, @code{HCDT}v, @code{HCDT}w, @code{const char *}opt)
+@end ifclear
+Fills the value of array according to the formula in string @var{eq}. Formula is an arbitrary expression depending  on variables @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Coordinates @samp{x}, @samp{y}, @samp{z} are supposed to be normalized in axis range. Variable @samp{u} is the original value of the array. Variables @samp{v} and @samp{w} are values of arrays @var{v}, @var{w} which can be @code{NULL} (i.e. can be omitted).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglGraph}} @code{void} Hist (@code{mglData &}res, @code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z, @code{const mglData &}a)
-@deftypefnx {Функция С} @code{int} mgl_hist_xyz (@code{HMGL} gr, @code{HMDT} res, @code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z, @code{const HMDT} a)
-Создет 3D распределение значений массива @var{a} в диапазоне [Min, Max].
+@deftypefn {Команда MGL} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
+@ifclear UDAV
+@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} PDE (@code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{float} dz=@code{0.1}, @code{float} k0=@code{100}, @code{const char *}opt=@code{""})
+@deftypefnx {Функция С} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{float} dz, @code{float} k0, @code{const char *}opt)
+@end ifclear
+Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{Min}, @var{Max} set the bounding box for the solution. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. At this moment, simplified form of function @var{ham} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this function is effectively @math{ham = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed. Here variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{ham = hre+i*him}). @sref{PDE solving hints}
 @end deftypefn
 
 
index edb4947c4d13ed44ca970140ce6585ec3cabec9f..55bea081c398b29a3de6fe1951d78e28ded2e05a 100644 (file)
@@ -6,11 +6,9 @@ This chapter describe commands for allocation, resizing, loading and saving, mod
 @end ifset
 
 @ifclear UDAV
-Class for working with data array. This class is defined in @code{#include <mgl/data.h>}. The class has functions for easy and safe allocation, resizing, loading and saving, modifying of data arrays. Also it can numerically differentiate and integrate data, interpolate, fill data by formula and so on. Class supports data with dimensions up to 3 (like function of 3 variables -- x,y,z). The internal representation of numbers is float. Float type was chosen because it has smaller size in memory and usually it has enough precision in plotting purposes. You can change it by selecting option @code{--enable-double} at the library configuring (see @ref{Installation}). Data arrays are denoted by Small Caps (like @sc{dat}) if it can be (re-)created by MGL commands.
+This chapter describe class @code{mglData} for working with data array. This class is defined in @code{#include <mgl/data.h>}. The class has functions for easy and safe allocation, resizing, loading and saving, modifying of data arrays. Also it can numerically differentiate and integrate data, interpolate, fill data by formula and so on. Class supports data with dimensions up to 3 (like function of 3 variables -- x,y,z). The internal representation of numbers is float. Float type was chosen because it has smaller size in memory and usually it has enough precision in plotting purposes. You can change it by selecting option @code{--enable-double} at the library configuring (see @ref{Installation}). Data arrays are denoted by Small Caps (like @sc{dat}) if it can be (re-)created by MGL commands.
 @end ifclear
 
-
-
 @menu
 * Public variables::
 * Data constructor::
@@ -56,7 +54,7 @@ Flag to use external data, i.e. don't delete it.
 
 @deftypefn {Method on @code{mglData}} @code{float} GetVal (@code{long} i)
 @deftypefnx {Method on @code{mglData}} @code{void} SetVal (@code{float} val, @code{long} i)
-Gets or sets the value in by "flat" index @var{i} without border checking. Index @var{i} should be in range [0, nx*ny*nz].
+Gets or sets the value in by "flat" index @var{i} without border checking. Index @var{i} should be in range [0, nx*ny*nz-1].
 @end deftypefn
 
 @deftypefn {Method on @code{mglData}} @code{long} GetNx ()
@@ -81,7 +79,7 @@ Returns pointer to internal data array.
 @c ------------------------------------------------------------------
 @node Data constructor, Data resizing, Public variables, Data processing
 @section Data constructor
-@cindex mglData constructor
+@cindex mglData
 
 @ifset UDAV
 There are many functions, which can create data for output (see @ref{Data filling}, @ref{File I/O}, @ref{Make another data}, @ref{Global functions}). Here I put most useful of them.
@@ -96,7 +94,7 @@ There are many functions, which can create data for output (see @ref{Data fillin
 @deftypefnx {C function} @code{HMDT} mgl_create_data ()
 @deftypefnx {C function} @code{HMDT} mgl_create_data_size (@code{int} mx, @code{int} my, @code{int} mz)
 @end ifclear
-Default constructor. Allocates the memory for data array and initializes it by zero. If string @var{eq} is specified then data will be filled by corresponding formula as in @code{Fill()} function.
+Default constructor. Allocates the memory for data array and initializes it by zero. If string @var{eq} is specified then data will be filled by corresponding formula as in @ref{fill} function.
 @end deftypefn
 
 @anchor{copy}
@@ -406,7 +404,7 @@ Sets the symbol @var{ids} for data columns. The string should contain one symbol
 @deftypefnx {Method on @code{mglData}} @code{void} Read (@code{const char *}fname)
 @deftypefnx {C function} @code{void} mgl_data_read (@code{HMDT} dat, @code{const char *}fname)
 @end ifclear
-Reads data from tab-separated text file with auto determining sizes of the data.
+Reads data from tab-separated text file with auto determining sizes of the data. Double newline means the beginning of new z-slice.
 @end deftypefn
 
 @deftypefn {MGL command} {} read @sc{dat} 'fname' @code{mx [my=1 mz=1]}
@@ -533,7 +531,7 @@ Extracts sub-array data from the original data array for indexes specified by ar
 @deftypefnx {Method on @code{mglData}} @code{mglData} Column (@code{const char *}eq) @code{const}
 @deftypefnx {C function} @code{HMDT} mgl_data_column (@code{HCDT} dat, @code{const char *}eq)
 @end ifclear
-Get column (or slice) of the data filled by formula @var{eq} on column ids. For example, @code{Column("n*w^2/exp(t)");}. The column ids must be defined first by @ref{idset} function. In MGL version this command usually is used as inline one @code{dat('eq')}.
+Get column (or slice) of the data filled by formula @var{eq} on column ids. For example, @code{Column("n*w^2/exp(t)");}. The column ids must be defined first by @ref{idset} function or read from files. In MGL version this command usually is used as inline one @code{dat('eq')}.
 @end deftypefn
 
 @anchor{resize}
@@ -766,7 +764,7 @@ Remove value steps (like phase jumps after inverse trigonometric functions) with
 @deftypefnx {Method on @code{mglData}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{float} delta=@code{0})
 @deftypefnx {C function} @code{void} mgl_data_smooth (@code{HMDT} dat, @code{const char *}dir, @code{float} delta)
 @end ifclear
-Smooths the data on specified direction or directions. Parameter @var{delta}>0 forbids to change values of array more than @var{delta} from the original ones. String @var{dirs} specifies the dimensions which will be smoothed. It may contain characters: @samp{x} for 1st dimension, @samp{y} for 2nd dimension, @samp{z} for 3d dimension. If string @var{dir} contain: @samp{0} then does nothing for @var{delta}=0 or approaches data to zero with the step @var{delta}, @samp{2} -- linear averaging over 3 points, @samp{5} -- linear averaging over 5 points. By default quadratic averaging over 5 points is used.
+Smooths the data on specified direction or directions. String @var{dirs} specifies the dimensions which will be smoothed. It may contain characters: @samp{x} for 1st dimension, @samp{y} for 2nd dimension, @samp{z} for 3d dimension. If string @var{dir} contain: @samp{0} then does nothing, @samp{3} -- linear averaging over 3 points, @samp{5} -- linear averaging over 5 points. By default quadratic averaging over 5 points is used.
 @end deftypefn
 
 @anchor{envelop}
@@ -805,11 +803,11 @@ Normalizes data slice-by-slice along direction @var{dir} the data in slices to r
 @node Interpolation, Data information, Data changing, Data processing
 @section Interpolation
 
-MGL can use linear interpolation by @ref{subdata} command, or spline interpolation by @ref{evaluate} command. Also you can use @ref{resize} for obtaining a data array with new sizes.
+MGL scripts can use linear interpolation by @ref{subdata} command, or spline interpolation by @ref{evaluate} command. Also you can use @ref{resize} for obtaining a data array with new sizes.
 
 @ifclear UDAV
 
-However, there are much faster functions in other modes (C/C++/Fortran/Python/...).
+However, there are much special faster functions in other modes (C/C++/Fortran/Python/...).
 
 @cindex Spline
 @deftypefn {Method on @code{mglData}} @code{float} Spline (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
@@ -836,7 +834,7 @@ Interpolates data by linear function to the given point @var{x}, @var{y}, @var{z
 @node Data information, Operators, Interpolation, Data processing
 @section Data information
 
-There are not so many functions for obtaining data properties in MGL language. However most of them can be found using "suffixes". Suffix can get some numerical value of the data array (like its size, maximal or minimal value, the sum of elements and so on) as number. Later it can be used as usual number in command arguments. The suffixes start from point @samp{.} right after (without spaces) variable name or its sub-array. For example, @code{a.nx} give the x-size of data @var{a}, @code{b(1).max} give maximal value of second row of variable @var{b}, @code{(c(:,0)^2).sum} give the sum of squares of elements in the first column of @var{c} and so on.
+There are a set of functions for obtaining data properties in MGL language. However most of them can be found using "suffixes". Suffix can get some numerical value of the data array (like its size, maximal or minimal value, the sum of elements and so on) as number. Later it can be used as usual number in command arguments. The suffixes start from point @samp{.} right after (without spaces) variable name or its sub-array. For example, @code{a.nx} give the x-size of data @var{a}, @code{b(1).max} give maximal value of second row of variable @var{b}, @code{(c(:,0)^2).sum} give the sum of squares of elements in the first column of @var{c} and so on.
 
 
 @cindex PrintInfo
@@ -903,9 +901,9 @@ Gets position of minimum to variables @var{i}, @var{j}, @var{k} and returns the
 @deftypefnx {C function} @code{float} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
 Gets position of maximum to variables @var{i}, @var{j}, @var{k} and returns the maximal value.
 @end deftypefn
-@deftypefn {Method on @code{mglData}} @code{float} Minimal (@code{float} &i, @code{float} &j, @code{float} &k) @code{const}
+@deftypefn {Method on @code{mglData}} @code{float} Minimal (@code{float} &x, @code{float} &y, @code{float} &z) @code{const}
 @deftypefnx {C function} @code{float} mgl_data_min_real (@code{HCDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
-Gets approximated (interpolated) position of minimum to variables @var{i}, @var{j}, @var{k} and returns the minimal value.
+Gets approximated (interpolated) position of minimum to variables @var{x}, @var{y}, @var{z} and returns the minimal value.
 @end deftypefn
 @end ifclear
 
@@ -914,10 +912,10 @@ Gets approximated (interpolated) position of minimum to variables @var{i}, @var{
 @deftypefnx {MGL suffix} {(dat)} .my
 @deftypefnx {MGL suffix} {(dat)} .mz
 @ifclear UDAV
-@deftypefnx {Method on @code{mglData}} @code{float} Maximal (@code{float} &i, @code{float} &j, @code{float} &k) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{float} Maximal (@code{float} &x, @code{float} &y, @code{float} &z) @code{const}
 @deftypefnx {C function} @code{float} mgl_data_max_real (@code{HCDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
 @end ifclear
-Gets approximated (interpolated) position of maximum to variables @var{i}, @var{j}, @var{k} and returns the maximal value.
+Gets approximated (interpolated) position of maximum to variables @var{x}, @var{y}, @var{z} and returns the maximal value.
 @end deftypefn
 
 
@@ -1000,7 +998,7 @@ Give first (for @code{.a}, i.e. @code{dat->a[0]}).
 Copies data from other variable.
 @end deftypefn
 
-@deftypefn {MGL command} {} copy dat [val]
+@deftypefn {MGL command} {} copy dat @code{val}
 @ifclear UDAV
 @deftypefnx {Method on @code{float}} @code{void} operator= (@code{float} val)
 @end ifclear
@@ -1009,108 +1007,76 @@ Set all data values equal to @var{val}.
 
 @anchor{multo}
 @deftypefn {MGL command} {} multo dat dat2
+@deftypefnx {MGL command} {} multo dat @code{val}
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{const mglData &}d)
-@deftypefnx {C function} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{HCDT} d)
-@end ifclear
-Multiplies the data by the other one for each element.
-@end deftypefn
-
-@deftypefn {MGL command} {} multo dat @code{val}
-@ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{HCDT} d)
 @deftypefnx {C function} @code{void} mgl_data_mul_num (@code{HMDT} dat, @code{float} d)
 @end ifclear
-Multiplies each element by the number.
+Multiplies data element by the other one or by value.
 @end deftypefn
 
 @anchor{divto}
 @deftypefn {MGL command} {} divto dat dat2
+@deftypefnx {MGL command} {} divto dat @code{val}
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{const mglData &}d)
-@deftypefnx {C function} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{HCDT} d)
-@end ifclear
-Divides the data by the other one for each element.
-@end deftypefn
-
-@deftypefn {MGL command} {} divto dat @code{val}
-@ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{HCDT} d)
 @deftypefnx {C function} @code{void} mgl_data_div_num (@code{HMDT} dat, @code{float} d)
 @end ifclear
-Divides each element by the number.
+Divides each data element by the other one or by value.
 @end deftypefn
 
+
 @anchor{addto}
 @deftypefn {MGL command} {} addto dat dat2
+@deftypefnx {MGL command} {} addto dat @code{val}
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{const mglData &}d)
-@deftypefnx {C function} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{HCDT} d)
-@end ifclear
-Adds the other data.
-@end deftypefn
-
-@deftypefn {MGL command} {} addto dat @code{val}
-@ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{HCDT} d)
 @deftypefnx {C function} @code{void} mgl_data_add_num (@code{HMDT} dat, @code{float} d)
 @end ifclear
-Adds the number to each element.
+Adds to each data element the other one or the value.
 @end deftypefn
 
 @anchor{subto}
 @deftypefn {MGL command} {} subto dat dat2
+@deftypefnx {MGL command} {} subto dat @code{val}
 @ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{const mglData &}d)
-@deftypefnx {C function} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{HCDT} d)
-@end ifclear
-Subtracts the other data.
-@end deftypefn
-
-@deftypefn {MGL command} {} subto dat @code{val}
-@ifclear UDAV
 @deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{HCDT} d)
 @deftypefnx {C function} @code{void} mgl_data_sub_num (@code{HMDT} dat, @code{float} d)
 @end ifclear
-Subtracts the number to each element.
+Subtracts from each data element the other one or the value.
 @end deftypefn
 
+
 @ifclear UDAV
 @deftypefn {Library Function} mglData operator+ (@code{const mglData &}a, @code{const mglData &}b)
-Adds the other data.
-@end deftypefn
-@deftypefn {Library Function} mglData operator+ (@code{float} a, @code{const mglData &}b)
-Adds the number.
-@end deftypefn
-@deftypefn {Library Function} mglData operator+ (@code{const mglData &}a, @code{float} b)
-Adds the number.
+@deftypefnx {Library Function} mglData operator+ (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator+ (@code{const mglData &}a, @code{float} b)
+Adds the other data or the number.
 @end deftypefn
 
 @deftypefn {Library Function} mglData operator- (@code{const mglData &}a, @code{const mglData &}b)
-Subtracts the other data.
-@end deftypefn
-@deftypefn {Library Function} mglData operator- (@code{float} a, @code{const mglData &}b)
-Subtracts from the number.
-@end deftypefn
-@deftypefn {Library Function} mglData operator- (@code{const mglData &}a, @code{float} b)
-Subtracts the number.
+@deftypefnx {Library Function} mglData operator- (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator- (@code{const mglData &}a, @code{float} b)
+Subtracts the other data or the number.
 @end deftypefn
 
 @deftypefn {Library Function} mglData operator* (@code{const mglData &}a, @code{const mglData &}b)
-Multiplies by the other data.
-@end deftypefn
-@deftypefn {Library Function} mglData operator* (@code{float} a, @code{const mglData &}b)
-Multiplies by the number.
-@end deftypefn
-@deftypefn {Library Function} mglData operator* (@code{const mglData &}a, @code{float} b)
-Multiplies by the number.
+@deftypefnx {Library Function} mglData operator* (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator* (@code{const mglData &}a, @code{float} b)
+Multiplies by the other data or the number.
 @end deftypefn
 
 @deftypefn {Library Function} mglData operator/ (@code{const mglData &}a, @code{const mglData &}b)
-Divides by the other data.
-@end deftypefn
-@deftypefn {Library Function} mglData operator/ (@code{const mglData &}a, @code{float} b)
-Divides by the number.
+@deftypefnx {Library Function} mglData operator/ (@code{const mglData &}a, @code{float} b)
+Divides by the other data or the number.
 @end deftypefn
 @end ifclear
 
@@ -1118,7 +1084,9 @@ Divides by the number.
 @node Global functions, Evaluate expression, Operators, Data processing
 @section Global functions
 
+@ifclear UDAV
 These functions are not methods of @code{mglData} class. However it provide additional functionality to handle data. So I put it in this chapter.
+@end ifclear
 
 @anchor{transform}
 @deftypefn {MGL command} {} transform @sc{dat} 'type' real imag
@@ -1213,7 +1181,7 @@ Computes triangulation for arbitrary placed points with coordinates @{@var{x},@v
 @section Evaluate expression
 
 @ifset UDAV
-You can use arbitrary formulas of existed data arrays or constants as any argument of data processing or data plotting commands. There are only 2 limitations: formula shouldn't contain spaces, and formula cannot be used as argument which will be (re)created by MGL command.
+You can use arbitrary formulas of existed data arrays or constants as any argument of data processing or data plotting commands. There are only 2 limitations: formula shouldn't contain spaces (to be recognized as single argument), and formula cannot be used as argument which will be (re)created by MGL command.
 @end ifset
 
 @ifclear UDAV
index e8859335633a0f6463ea9b59c6866078a97f9e63..acb83afe7aaf7ea57a5af7ca093b17a1f258652f 100644 (file)
@@ -1,26 +1,39 @@
 @c ------------------------------------------------------------------
-@chapter Ð\9aлаÑ\81Ñ\81 mglData
+@chapter Ð\9eбÑ\80абоÑ\82ка Ð´Ð°Ð½Ð½Ñ\8bÑ\85
 
-Это класс для работы с массивами данных, определенный в @code{#include <mgl/mgl_data.h>}. Он содержит функции для выделения памяти и изменения размера данных, чтения данных из файла, численного дифференцирования/интегрирования/интерполяции и пр., заполнения по текстовой формуле и т.д. Класс позволяет работать с данными размерности не более 3 (как функции от трех переменных -- x,y,z). По умолчанию внутреннее представление данных -- float, выбранный в силу меньшего размера занимаемой памяти и достаточной для построения графиков точности. Базовый тип можно сменить на этапе установки (@pxref{Installation and usage}) указав опцию @code{--enable-double}. Однако, в дальнейшем в документации будет использован тип @code{float}.
 
-@menu
+@ifset UDAV
+В данной главе описываются команды для работы с массивами данных. Они включают команды для выделения памяти и изменения размера данных, чтения данных из файла, численного дифференцирования, интегрирования, интерполяции и пр., заполнения по текстовой формуле и т.д. Класс позволяет работать с данными размерности не более 3 (как функции от трёх переменных -- x,y,z). По умолчанию внутреннее представление данных -- float, выбранный в силу меньшего размера занимаемой памяти и достаточной для построения графиков точности. Базовый тип можно сменить на этапе установки (@pxref{Installation and usage}) указав опцию @code{--enable-double}. Массивы которые могут быть созданы командами MGL отображаются Small Caps шрифтом (например, @sc{dat}).
+@end ifset
+
+@ifclear UDAV
+В данной главе описывается класс @code{mglData} для работы с массивами данных, определённый в @code{#include <mgl/mgl_data.h>}. Он содержит функции для выделения памяти и изменения размера данных, чтения данных из файла, численного дифференцирования, интегрирования, интерполяции и пр., заполнения по текстовой формуле и т.д. Класс позволяет работать с данными размерности не более 3 (как функции от трёх переменных -- x,y,z). По умолчанию внутреннее представление данных -- float, выбранный в силу меньшего размера занимаемой памяти и достаточной для построения графиков точности. Базовый тип можно сменить на этапе установки (@pxref{Installation and usage}) указав опцию @code{--enable-double}. Однако, в дальнейшем в документации будет использован тип @code{float}. Массивы которые могут быть созданы командами MGL отображаются Small Caps шрифтом (например, @sc{dat}).
+@end ifclear
+
 * Public variables::
-* Data create::
-* Fill::
-* Rearrange::
+* Data constructor::
+* Data resizing::
+* Data filling::
 * File I/O::
 * Make another data::
-* Change data::
+* Data changing::
 * Interpolation::
-* Informational functions::
+* Data information::
 * Operators::
 * Global functions::
+* Evaluate expression::
 @end menu
 
 @c ------------------------------------------------------------------
-@node Public variables, Data create, , Data processing
+@node Public variables, Data constructor, , Data processing
 @section Переменные
 
+
+@ifset UDAV
+MGL не поддерживает прямой доступ к элементам массива. См. раздел @ref{Data filling}
+@end ifset
+
+@ifclear UDAV
 @deftypecv {Variable} mglData @code{float *} a
 Указатель на массив данных. Это одномерный массив. Например, матрица [nx x ny x nz] представляется одномерным массивом длиной nx*ny*nz, где элемент с индексами @{i, j, k@} находится как a[i+nx*j+nx*ny*k] (индексы отсчитываются от нуля).
 @end deftypecv
 @deftypecv {Variable} mglData @code{char *} id
 Имена колонки (или среза при nz>1) -- один символ на колонку.
 @end deftypecv
+@deftypecv {Variable} mglData @code{bool} link
+Флаг использования указателя на внешние данные, включает запрет на удаление массива данных.
+@end deftypecv
 
-
-@c ------------------------------------------------------------------
-@node Data create, Fill, Public variables, Data processing
-@section Создание и удаление
-@cindex mglData
-@cindex Set
-
-@defop Конструктор @code{mglData} @code{} mglData (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
-Конструктор по умолчанию. Выделяет память для массива данных и заполняет ее нулями.
-@end defop
-@defop Конструктор @code{mglData} @code{} mglData (@code{const char *}fname)
-Читает данные из файла.
-@end defop
-@defop Конструктор @code{mglData} @code{} mglData (@code{const mglData} &dat)
-Копирует данные из другого экземпляра @code{mglData}.
-@end defop
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_create (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
-Создает/пересоздает массив данных указанного размера и заполняет его нулями. Ничего не делает при @var{mx}, @var{my}, @var{mz} отрицательных или равных нулю.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
-@deftypefnx {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_set_float (@code{HMDT} dat, @code{const float *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
-@deftypefnx {Функция С} @code{void} mgl_data_set_double (@code{HMDT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
-Выделяет память и копирует данные из массивов типа @code{float*} или @code{double*}, т.е. из массивов определенных как @code{float a[NX*NY*NZ];}.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const float **}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const double **}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Функция С} @code{void} mgl_data_set_float2 (@code{HMDT} dat, @code{const float **}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Функция С} @code{void} mgl_data_set_double2 (@code{HMDT} dat, @code{const double **}A, @code{int} N1, @code{int} N2)
-Выделяет память и копирует данные из массивов типа @code{float**} или @code{double**} с размерностями @var{N1}, @var{N2}, т.е. из массивов определенных как @code{float a[N1][N2];}.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const float ***}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const double ***}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Функция С} @code{void} mgl_data_set_float3 (@code{HMDT} dat, @code{const float ***}A, @code{int} N1, @code{int} N2)
-@deftypefnx {Функция С} @code{void} mgl_data_set_double3 (@code{HMDT} dat, @code{const double ***}A, @code{int} N1, @code{int} N2)
-Выделяет память и копирует данные из массивов типа @code{float***} или @code{double***} с размерностями @var{N1}, @var{N2}, @var{N3}, т.е. из массивов определенных как @code{float a[N1][N2][N3];}.
+@deftypefn {Method on @code{mglData}} @code{float} GetVal (@code{long} i)
+@deftypefnx {Method on @code{mglData}} @code{void} SetVal (@code{float} val, @code{long} i)
+Присваивает или возвращает значение используя "непрерывную" индексацию без проверки выхода за границы массива. Индекс @var{i} должен быть в диапазоне [0, nx*ny*nz-1].
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{gsl_vector *}v)
-@deftypefnx {Функция С} @code{void} mgl_data_set_vector (@code{HMDT} dat, @code{gsl_vector *}v)
-Выделяет память и копирует данные из структуры типа @code{gsl_vector *}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{gsl_matrix *}m)
-@deftypefnx {Функция С} @code{void} mgl_data_set_matrix (@code{HMDT} dat, @code{gsl_matrix *}m)
-Выделяет память и копирует данные из структуры типа @code{gsl_matrix *}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{inline void} Set (@code{const mglData &}from)
-@deftypefnx {Функция С} @code{void} mgl_data_set (@code{HMDT} dat, @code{const HMDT} from)
-Выделяет память и копирует данные из другого экземпляра @var{from}.
+@deftypefn {Method on @code{mglData}} @code{long} GetNx ()
+@deftypefnx {Method on @code{mglData}} @code{long} GetNy ()
+@deftypefnx {Method on @code{mglData}} @code{long} GetNz ()
+@deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
+@deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
+@deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
+Возвращает размер данных в направлении x, y и z соответственно.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const std::vector<int> &}d)
-@deftypefnx {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const std::vector<float> &}d)
-@deftypefnx {Метод класса @code{mglData} (C++)} @code{void} Set (@code{const std::vector<double> &}d)
\92Ñ\8bделÑ\8fеÑ\82 Ð¿Ð°Ð¼Ñ\8fÑ\82Ñ\8c Ð¸ ÐºÐ¾Ð¿Ð¸Ñ\80Ñ\83еÑ\82 Ð´Ð°Ð½Ð½Ñ\8bе Ð¸Ð· Ð¼Ð°Ñ\81Ñ\81ива Ñ\82ипа @code{std::vector<T>}.
+@deftypefn {C function} @code{float} mgl_data_get_value (@code{HCDT} dat, @code{int} i, @code{int} j, @code{int} k)
+@deftypefnx {C function} @code{float *} mgl_data_value (@code{HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
+@deftypefnx {C function} @code{void} mgl_data_set_value (@code{HMDT} dat, @code{float} v, @code{int} i, @code{int} j, @code{int} k)
\9fÑ\80иÑ\81ваиваеÑ\82 Ð¸Ð»Ð¸ Ð²Ð¾Ð·Ð²Ñ\80аÑ\89аеÑ\82 Ð·Ð½Ð°Ñ\87ение Ñ\8fÑ\87ейки Ð´Ð°Ð½Ð½Ñ\8bÑ\85 Ñ\81 Ð¿Ñ\80овеÑ\80кой Ð²Ñ\8bÑ\85ода Ð·Ð° Ð¿Ñ\80еделÑ\8b Ð¼Ð°Ñ\81Ñ\81ива.
 @end deftypefn
-
-
-@deftypefn {Метод класса @code{mglData} (C+, Python)} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
-Выделяет память и сканирует (scanf) данные из строки.
+@deftypefn {C function} @code{const float *} mgl_data_data (@code{HCDT} dat)
+Возвращает указатель на внутренний массив данных.
 @end deftypefn
+@end ifclear
 
 @c ------------------------------------------------------------------
-@node Fill, Rearrange, Data create, Data processing
-@section Заполнение данных
-@cindex Fill
-@cindex Modify
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Fill (@code{float} x1, @code{float} x2, @code{char} dir=@code{'x'})
-@deftypefnx {Функция С} @code{void} mgl_data_fill (@code{HMDT} dat, @code{float} x1, @code{float} x2, @code{char} dir)
-Заполняет значениями равно распределенными в диапазоне [@var{x1}, @var{x2}] в направлении @var{dir}=@{@samp{x},@samp{y},@samp{z}@}.
-@end deftypefn
+@node Data constructor, Data resizing, Public variables, Data processing
+@section Создание и удаление данных
+@cindex mglData
+@cindex Set
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Fill (@code{const char *}eq, @code{mglPoint} Min, @code{mglPoint} Max, @code{const mglData *}vdat=0, @code{const mglData *}wdat=0)
-@deftypefnx {Функция С} @code{void} mgl_data_fill (@code{HMGL} gr, @code{HMDT} dat, @code{const char *}eq, @code{const HMDT *}vdat, @code{const HMDT *}wdat)
-Заполняет значениями вычисленными по формуле @var{eq}. Формула представляет собой произвольное выражение, зависящее от переменных @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Координаты @samp{x}, @samp{y}, @samp{z} полагаются меняющимися в диапазоне @var{Min} x @var{Max} (в отличие от функции @code{Modify}). Переменная @samp{u} -- значения исходного массива, переменные @samp{v}, @samp{w} -- значения массивов @var{vdat}, @var{wdat}. Последние могут быть @code{NULL}, т.е. опущены.
-@end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
-@deftypefnx {Метод класса @code{mglData} (C++, Python)} @code{void} Modify (@code{const char *}eq, @code{const mglData &}v)
-@deftypefnx {Метод класса @code{mglData} (C++, Python)} @code{void} Modify (@code{const char *}eq, @code{const mglData &}v, @code{const mglData &}w)
-@deftypefnx {Функция С} @code{void} mgl_data_modify (@code{HMDT} dat, @code{const char *}eq, @code{int} dim)
-@deftypefnx {Функция С} @code{void} mgl_data_modify_vw (@code{HMDT} dat, @code{const char *}eq, @code{const HMDT} v, @code{const HMDT} w)
-Заполняет значениями вычисленными по формуле @var{eq}. Формула представляет собой произвольное выражение, зависящее от переменных @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Координаты @samp{x}, @samp{y}, @samp{z} полагаются меняющимися в диапазоне [0,1] (в отличие от функции @code{Fill}). Переменная @samp{u} -- значения исходного массива, переменные @samp{v}, @samp{w} -- значения массивов @var{vdat}, @var{wdat}. Последние могут быть @code{NULL}, т.е. опущены. Если указан @var{dim}>0, то изменяются только слои >=@var{dim}.
-@end deftypefn
+@ifset UDAV
+There are many functions, which can create data for output (see @ref{Data filling}, @ref{File I/O}, @ref{Make another data}, @ref{Global functions}). Here I put most useful of them.
+@end ifset
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Put (@code{float} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
-@deftypefnx mglData @code{void} mgl_data_put_val (@code{HMDT} a, @code{float} val, @code{int} i, @code{int} j, @code{int} k)
-Присваивает значения (под-)массива @var{dat}[@var{i}, @var{j}, @var{k}] = @var{val}. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают значениия @var{val} для всего диапазона соответствующего направления(ий). Например, @code{Put(val,-1,0,-1);} задает a[i,0,j]=@var{val} для i=0...(nx-1), j=0...(nz-1).
+@anchor{new}
+@deftypefn {MGL command} {} new @sc{dat} [@code{nx=1} 'eq']
+@deftypefnx {MGL command} {} new @sc{dat} @code{nx ny} ['eq']
+@deftypefnx {MGL command} {} new @sc{dat} @code{nx ny nz} ['eq']
+@ifclear UDAV
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
+@deftypefnx {C function} @code{HMDT} mgl_create_data ()
+@deftypefnx {C function} @code{HMDT} mgl_create_data_size (@code{int} mx, @code{int} my, @code{int} mz)
+@end ifclear
+Выделяет память для массива данных и заполняет её нулями. Если указана формула @var{eq}, то данные заполняются также как при использовании @ref{fill}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Put (@code{const mglData &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
-@deftypefnx mglData @code{void} mgl_data_put_dat (@code{HMDT} a, @code{const HMDT} v, @code{int} i, @code{int} j, @code{int} k)
-Копирует значения из массива @var{v} в диапазон значений данного массива. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают диапазон изменения значений в соответствующих направление(ях). Младшие размерности массива @var{v} должны быть больше выбранного диапазона массива. Например, @code{Put(v,-1,0,-1);} присвоитa[i,0,j]=@var{v}.ny>nz ? @var{v}.a[i,j] : @var{v}.a[i], где i=0...(nx-1), j=0...(nz-1) и условие v.nx>=nx выполнено.
+@anchor{copy}
+@deftypefn {MGL command} {} copy @sc{dat} dat2 ['eq'='']
+@deftypefnx {MGL command} {} copy @sc{dat} @code{val}
+@ifclear UDAV
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const mglData &}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const mglDataA *}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{const float *}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const float *}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{const double *}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const double *}dat2)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size)
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size, @code{int} cols)
+@end ifclear
+Копирует данные из другого экземпляра данных. Если указана формула @var{eq}, то данные заполняются также как при использовании @ref{fill}.
 @end deftypefn
 
-@deftypefn {Функция С} @code{void} mgl_data_set_value (@code{HMDT} dat, @code{float} v, @code{int} i, @code{int} j, @code{int} k)
-Присваивает значение выбранной ячейке массива данных.
+@deftypefn {MGL command} {} read @sc{dat} 'fname'
+@ifclear UDAV
+@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const char *}fname)
+@deftypefnx {C function} @code{HMDT} mgl_create_data_file (@code{const char *}fname)
+@end ifclear
+Читает данные из текстового файла с автоматическим определением размеров массива.
 @end deftypefn
 
-@deftypefn {Функция С} @code{float} mgl_data_get_value (@code{HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
-Возвращает значение выбранной ячейки массива данных.
+@deftypefn {MGL command} {} delete dat
+@ifclear UDAV
+@deftypefnx {Destructor on @code{mglData}} {} ~mglData ()
+@deftypefnx {C function} @code{void} mgl_delete_data (@code{HMDT} dat)
+@end ifclear
+Удаляет массив данных из памяти.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C+, Python)} @code{void} GetNx ()
-@deftypefnx {Функция С} @code{float} mgl_data_get_nx (@code{HMDT} dat)
-Возвращает размер по x-направлению.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C+, Python)} @code{void} GetNy ()
-@deftypefnx {Функция С} @code{float} mgl_data_get_ny (@code{HMDT} dat)
-Возвращает размер по y-направлению.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C+, Python)} @code{void} GetNz ()
-@deftypefnx {Функция С} @code{float} mgl_data_get_nz (@code{HMDT} dat)
-Возвращает размер по z-направлению.
-@end deftypefn
 
 @c ------------------------------------------------------------------
-@node Rearrange, File I/O, Fill, Data processing
+@node Data resizing, Data filling, Data constructor, Data processing
 @section Изменение размеров данных
+@cindex Create
 @cindex Rearrange
 @cindex Extend
 @cindex Transpose
 @cindex Squeeze
 @cindex Crop
-@cindex InsertRows
-@cindex InsertColumns
-@cindex InsertSlices
-@cindex DeleteRows
-@cindex DeleteColumns
-@cindex DeleteSlices
 @cindex Insert
 @cindex Delete
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_data_rearrange (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
+
+@deftypefn {MGL command} {} new @sc{dat} [@code{nx=1 ny=1 nz=1}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_create (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
+@end ifclear
+Создает/пересоздает массив данных указанного размера и заполняет его нулями. Ничего не делает при @var{mx}, @var{my}, @var{mz} отрицательных или равных нулю.
+@end deftypefn
+
+@anchor{rearrange}
+@deftypefn {MGL command} {} rearrange dat @code{mx [my=0 mz=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
+@deftypefnx {C function} @code{void} mgl_data_rearrange (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
+@end ifclear
 Изменяет размерность данных без изменения самого массива данных, так что результирующий массив @var{mx}*@var{my}*@var{mz} < nx*ny*nz. Если один из параметров @var{my} или @var{mz} ноль, то он будет выбран оптимальным образом. Например, если @var{my}=0, то будет @var{my}=nx*ny*nz/@var{mx} и @var{mz}=1.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_data_extend (@code{HMDT} dat, @code{int} n1, @code{int} n2)
+@anchor{transpose}
+@deftypefn {MGL command} {} transpose dat ['dim'='yxz']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
+@deftypefnx {C function} @code{void} mgl_data_transpose (@code{const char *}dim)
+@end ifclear
+Транспонирует (меняет порядок размерностей) массив данных. Новый порядок размерностей задается строкой @var{dim}. Функция может быть полезна для транспонирования одномерных (или квазиодномерных) массивов после чтения их из файла.
+@end deftypefn
+
+@anchor{extend}
+@deftypefn {MGL command} {} extend dat @code{n1 [n2=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
+@deftypefnx {C function} @code{void} mgl_data_extend (@code{HMDT} dat, @code{int} n1, @code{int} n2)
+@end ifclear
 Увеличивает размер данных путем вставки (|@var{n1}|+1) новых срезов после (для @var{n1}>0) или перед (для @var{n1}<0) существующими данными. Можно добавить сразу 2 размерности для 1d массива, используя второй параметр @var{n2}. Данные в новые срезы будут скопированы из существующих. Например, для @var{n1}>0 новый массив будет
 @iftex
 @math{a_{ij}^{new} = a_i^{old}} where j=0...@var{n1}. Соответственно, для @var{n1}<0 новый массив будет @math{a_{ij}^{new} = a_j^{old}}, где i=0...|@var{n1}|.
@@ -194,14 +187,13 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @end ifnottex
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
-@deftypefnx {Функция С} @code{void} mgl_data_transpose (@code{const char *}dim)
-Транспонирует (меняет порядок размерностей) массив данных. Новый порядок размерностей задается строкой @var{dim}.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
-@deftypefnx {Функция С} @code{void} mgl_data_squeeze (@code{HMDT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
-Уменьшает размер данных путем удаления элементов с индексами не кратными @var{rx}, @var{ry}, @var{rz} соответственно. Параметр @var{smooth} задает использовать сглаживания
+@anchor{squeeze}
+@deftypefn {MGL command} {} squeeze dat @code{rx [ry=1 rz=1 sm=off]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
+@deftypefnx {C function} @code{void} mgl_data_squeeze (@code{HMDT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
+@end ifclear
+Уменьшает размер данных путём удаления элементов с индексами не кратными @var{rx}, @var{ry}, @var{rz} соответственно. Параметр @var{smooth} задает использовать сглаживания
 @iftex
 (т.е. @math{a_{out}[i]=\sum_{j=i,i+r}a[j]/r}) или нет (т.е. @math{a_{out}[i]=a[j*r]}).
 @end iftex
@@ -210,150 +202,382 @@ a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @v
 @end ifnottex
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
-@deftypefnx {Функция С} @code{void} mgl_data_crop (@code{HMDT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
+@anchor{crop}
+@deftypefn {MGL command} {} crop dat @code{n1 n2} 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
+@deftypefnx {C function} @code{void} mgl_data_crop (@code{HMDT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
+@end ifclear
 Обрезает границы данных при @var{i}<@var{n1} и @var{i}>@var{n2} (при @var{n2}>0) или @var{i}>@code{n[xyz]}-@var{n2} (при @var{n2}<=0) вдоль направления @var{dir}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} InsertRows (@code{int} at, @code{int} num=@code{1}, @code{const char *}eq=@code{NULL})
-Вставляет @var{num} срезов вдоль направления 'y' (строк) с позиции @var{at} и заполняет их по формуле @var{eq} (при @var{eq}!=0) или нулями.
+@anchor{insert}
+@deftypefn {MGL command} {} insert dat 'dir' @code{[pos=off num=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_insert (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
+@end ifclear
+Вставляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos} и заполняет их нулями.
+@end deftypefn
+
+@anchor{delete}
+@deftypefn {MGL command} {} delete dat 'dir' @code{[pos=off num=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_delete (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
+@end ifclear
+Удаляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos}.
+@end deftypefn
+
+@anchor{sort}
+@deftypefn {MGL command} {} sort dat @code{idx [idy=-1]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Sort (@code{lond} idx, @code{long} idy=@code{-1})
+@deftypefnx {C function} @code{void} mgl_data_sort (@code{HMDT} dat, @code{lond} idx, @code{long} idy)
+@end ifclear
+Сортирует строки (или срезы в 3D случае) по значениям в указанной колонке @var{idx} (или ячейках @{@var{idx},@var{idy}@} для 3D случая).
+@end deftypefn
+
+
+@c ------------------------------------------------------------------
+@node Data filling, File I/O, Data resizing, Data processing
+@section Заполнение данных
+@cindex Fill
+@cindex Modify
+@cindex Set
+@cindex List
+@cindex Var
+
+@anchor{list}
+@deftypefn {MGL command} {} list @sc{dat} @code{v1 ...}
+Создает новый массив данных @var{dat} и заполняет его числовыми значениями аргументов @code{v1 ...}. Команда может создавать одно- и двухмерные массивы с произвольными значениями. Для создания 2d массива следует использовать разделитель @samp{|}, который означает начало новой строки данных. Размер массива данных будет [maximal of row sizes * number of rows]. Например, команда @code{list 1 | 2 3} создаст массив [1 0; 2 3]. Замечу, что максимальное число аргументов равно 1000.
+@end deftypefn
+@deftypefn {MGL command} {} list @sc{dat} d1 ...
+Создает новый массив данных @var{dat} и заполняет его значениями из массивов @var{d1 ...}. Команда может создавать двух- и трёхмерные (если аргументы -- двумерные массивы) массивы. Меньшая размерность всех массивов в аргументах должна совпадать. В противном случае аргумент (массив) будет пропущен.
+@end deftypefn
+
+@ifclear UDAV
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_set_float (@code{HMDT} dat, @code{const float *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
+@deftypefnx {C function} @code{void} mgl_data_set_double (@code{HMDT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
+Выделяет память и копирует данные из массивов типа @code{float*} или @code{double*}, т.е. из массивов определённых как @code{float a[NX*NY*NZ];}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} InsertColumns (@code{int} at, @code{int} num=@code{1}, @code{const char *}eq=@code{NULL})
-Вставляет @var{num} срезов вдоль направления 'x' (колонок) с позиции @var{at} и заполняет их по формуле @var{eq} (при @var{eq}!=0) или нулями.
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float **}A, @code{int} N1, @code{int} N2)
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double **}A, @code{int} N1, @code{int} N2)
+@deftypefnx {C function} @code{void} mgl_data_set_float2 (@code{HMDT} dat, @code{const float **}A, @code{int} N1, @code{int} N2)
+@deftypefnx {C function} @code{void} mgl_data_set_double2 (@code{HMDT} dat, @code{const double **}A, @code{int} N1, @code{int} N2)
+Выделяет память и копирует данные из массивов типа @code{float**} или @code{double**} с размерностями @var{N1}, @var{N2}, т.е. из массивов определённых как @code{float a[N1][N2];}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} InsertSlices (@code{int} at, @code{int} num=@code{1}, @code{const char *}eq=@code{NULL})
-Вставляет @var{num} срезов вдоль направления 'z' с позиции @var{at} и заполняет их по формуле @var{eq} (при @var{eq}!=0) или нулями.
+
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float ***}A, @code{int} N1, @code{int} N2)
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double ***}A, @code{int} N1, @code{int} N2)
+@deftypefnx {C function} @code{void} mgl_data_set_float3 (@code{HMDT} dat, @code{const float ***}A, @code{int} N1, @code{int} N2)
+@deftypefnx {C function} @code{void} mgl_data_set_double3 (@code{HMDT} dat, @code{const double ***}A, @code{int} N1, @code{int} N2)
+Выделяет память и копирует данные из массивов типа @code{float***} или @code{double***} с размерностями @var{N1}, @var{N2}, @var{N3}, т.е. из массивов определённых как @code{float a[N1][N2][N3];}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} DeleteRows (@code{int} at, @code{int} num=@code{1})
-Удаляет @var{num} срезов вдоль направления 'y' (строк) с позиции @var{at}.
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{gsl_vector *}v)
+@deftypefnx {C function} @code{void} mgl_data_set_vector (@code{HMDT} dat, @code{gsl_vector *}v)
+Выделяет память и копирует данные из структуры типа @code{gsl_vector *}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} DeleteColumns (@code{int} at, @code{int} num=@code{1})
-Удаляет @var{num} срезов вдоль направления 'x' (колонок) с позиции @var{at}.
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{gsl_matrix *}m)
+@deftypefnx {C function} @code{void} mgl_data_set_matrix (@code{HMDT} dat, @code{gsl_matrix *}m)
+Выделяет память и копирует данные из структуры типа @code{gsl_matrix *}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} DeleteSlices (@code{int} at, @code{int} num=@code{1})
-Удаляет @var{num} срезов вдоль направления 'z' с позиции @var{at}.
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const mglData &}from)
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{HCDT} from)
+@deftypefnx {C function} @code{void} mgl_data_set (@code{HMDT} dat, @code{HCDT} from)
+Выделяет память и копирует данные из другого экземпляра данных @var{from}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_insert (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
-Вставляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos} и заполняет их нулями.
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const std::vector<int> &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const std::vector<float> &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const std::vector<double> &}d)
+Выделяет память и копирует данные из массива типа @code{std::vector<T>}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_delete (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
-Удаляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos}.
+
+@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
+Выделяет память и сканирует массив данных из строки.
+@end deftypefn
+
+@deftypefn {Method on @code{mglData}} @code{void} Link (@code{const mglData &}from)
+@deftypefnx {Method on @code{mglData}} @code{void} Link (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_link (@code{HMDT} dat, @code{const float *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
+Устанавливает флаг использования внешнего массива данных, которые не будут удалены. Флаг может быть возвращён в исходное состояние и создан новый внутренний массив если использовались функции изменяющие размер данных.
+@end deftypefn
+@end ifclear
+
+@anchor{var}
+@deftypefn {MGL command} {} var @sc{dat} @code{num v1 [v2=nan]}
+Создает новый одномерный массив данных @var{dat} размером @var{num}, и заполняет его равномерно в диапазоне [@var{v1}, @var{v2}]. Если @var{v2}=@code{nan}, то используется @var{v2=v1}.
+@end deftypefn
+
+@anchor{fill}
+@deftypefn {MGL command} {} fill dat v1 v2 ['dir'='x']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{float} v1, @code{float} v2, @code{char} dir=@code{'x'})
+@deftypefnx {C function} @code{void} mgl_data_fill (@code{HMDT} dat, @code{float} v1, @code{float} v2, @code{char} dir)
+@end ifclear
+Заполняет значениями равно распределёнными в диапазоне [@var{x1}, @var{x2}] в направлении @var{dir}=@{@samp{x},@samp{y},@samp{z}@}.
+@end deftypefn
+
+@deftypefn {MGL command} {} fill dat 'eq'
+@deftypefnx {MGL command} {} fill dat 'eq' vdat
+@deftypefnx {MGL command} {} fill dat 'eq' vdat wdat
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const char *}opt=@code{""})
+@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglData &}vdat, @code{const char *}opt=@code{""})
+@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglData &}vdat, @code{const mglData &}wdat, @code{const char *}opt=@code{""})
+@deftypefnx {C function} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} dat, @code{const char *}eq, @code{const HMDT *}vdat, @code{const HMDT *}wdat, @code{const char *}opt)
+@end ifclear
+Заполняет значениями вычисленными по формуле @var{eq}. Формула представляет собой произвольное выражение, зависящее от переменных @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Координаты @samp{x}, @samp{y}, @samp{z} полагаются меняющимися в диапазоне @var{Min} x @var{Max} (в отличие от функции @code{Modify}). Переменная @samp{u} -- значения исходного массива, переменные @samp{v}, @samp{w} -- значения массивов @var{vdat}, @var{wdat}. Последние могут быть @code{NULL}, т.е. опущены.
+@end deftypefn
+
+@anchor{modify}
+@deftypefn {MGL command} {} modify dat 'eq' [@code{dim=0}]
+@deftypefnx {MGL command} {} modify dat 'eq' vdat
+@deftypefnx {MGL command} {} modify dat 'eq' vdat wdat
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
+@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglData &}v)
+@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglData &}v, @code{const mglData &}w)
+@deftypefnx {C function} @code{void} mgl_data_modify (@code{HMDT} dat, @code{const char *}eq, @code{int} dim)
+@deftypefnx {C function} @code{void} mgl_data_modify_vw (@code{HMDT} dat, @code{const char *}eq, @code{HCDT} v, @code{HCDT} w)
+@end ifclear
+Аналогично предыдущему с координатами @samp{x}, @samp{y}, @samp{z}, меняющимися в диапазоне [0,1]. Если указан @var{dim}>0, то изменяются только слои >=@var{dim}.
+@end deftypefn
+
+@anchor{fillsample}
+@deftypefn {MGL command} {} fillsample dat 'how'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} FillSample (@code{const char *}how)
+@deftypefnx mglData @code{void} mgl_data_fill_sample (@code{HMDT} a, @code{const char *}how)
+@end ifclear
+Заполняет массив данных 'x' или 'k' значениями для преобразований Ханкеля ('h') или Фурье ('f').
+@end deftypefn
+
+
+@anchor{put}
+@deftypefn {MGL command} {} put dat @code{val [i=: j=: k=:]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Put (@code{float} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
+@deftypefnx mglData @code{void} mgl_data_put_val (@code{HMDT} a, @code{float} val, @code{int} i, @code{int} j, @code{int} k)
+@end ifclear
+Присваивает значения (под-)массива @var{dat}[@var{i}, @var{j}, @var{k}] = @var{val}. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают значения @var{val} для всего диапазона соответствующего направления(ий). Например, @code{Put(val,-1,0,-1);} задает a[i,0,j]=@var{val} для i=0...(nx-1), j=0...(nz-1).
+@end deftypefn
+
+@deftypefn {MGL command} {} put dat vdat [@code{i=: j=: k=:}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Put (@code{const mglData &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
+@deftypefnx mglData @code{void} mgl_data_put_dat (@code{HMDT} a, @code{HCDT} v, @code{int} i, @code{int} j, @code{int} k)
+@end ifclear
+Копирует значения из массива @var{v} в диапазон значений данного массива. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают диапазон изменения значений в соответствующих направление(ях). Младшие размерности массива @var{v} должны быть больше выбранного диапазона массива. Например, @code{Put(v,-1,0,-1);} присвоит a[i,0,j]=@var{v}.ny>nz ? @var{v}.a[i,j] : @var{v}.a[i], где i=0...(nx-1), j=0...(nz-1) и условие v.nx>=nx выполнено.
+@end deftypefn
+
+@anchor{idset}
+@deftypefn {MGL command} {} idset dat 'ids'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} SetColumnId (@code{const char *}ids)
+@deftypefnx mglData @code{void} mgl_data_set_id (@code{const char *}ids)
+@end ifclear
+Задает названия @var{ids} для колонок массива данных. Строка должна содержать один символ 'a'...'z' на колонку. Эти названия используются в функции @ref{column}.
 @end deftypefn
 
+
 @c ------------------------------------------------------------------
-@node File I/O, Make another data, Rearrange, Data processing
+@node File I/O, Make another data, Data filling, Data processing
 @section Чтение/сохранение данных
 @cindex Read
 @cindex ReadMat
-@cindex ReadAll
 @cindex ReadRange
-@cindex ReadHDF
+@cindex ReadAll
 @cindex Save
+@cindex ReadHDF
 @cindex SaveHDF
-@cindex Export
 @cindex Import
+@cindex Export
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Read (@code{const char *}fname)
-@deftypefnx {Функция С} @code{void} mgl_data_read (@code{HMDT} dat, @code{const char *}fname)
+@anchor{read}
+@deftypefn {MGL command} {} read @sc{dat} 'fname'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Read (@code{const char *}fname)
+@deftypefnx {C function} @code{void} mgl_data_read (@code{HMDT} dat, @code{const char *}fname)
+@end ifclear
 Читает данные из текстового файла с разделителями символом пробела/табуляции с автоматическим определением размера массива. Двойной перевод строки начинает новый срез данных (по направлению z).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_read_dim (@code{HMDT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
+@deftypefn {MGL command} {} read @sc{dat} 'fname' @code{mx [my=1 mz=1]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_read_dim (@code{HMDT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
+@end ifclear
 Читает данные из текстового файла с заданными размерами. Ничего не делается если параметры @var{mx}, @var{my} или @var{mz} равны нулю или отрицательны.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
-@deftypefnx {Функция С} @code{void} mgl_data_read_mat (@code{HMDT} dat, @code{const char *}fname, @code{int} dim)
+@anchor{readmat}
+@deftypefn {MGL command} {} readmat @sc{dat} 'fname' [@code{dim=2}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
+@deftypefnx {C function} @code{void} mgl_data_read_mat (@code{HMDT} dat, @code{const char *}fname, @code{int} dim)
+@end ifclear
 Читает данные из текстового файла с размерами, указанными в первых @var{dim} числах файла. При этом переменная @var{dim} задает размерность (1d, 2d, 3d) данных.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} ReadRange (@code{const char *}templ, @code{float} from, @code{float} to, @code{float} step=@code{1.f}, @code{bool} as_slice=@code{false})
+@anchor{readall}
+@deftypefn {MGL command} {} readall @sc{dat} 'templ' @code{v1 v2 [dv=1 slice=off]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} ReadRange (@code{const char *}templ, @code{float} from, @code{float} to, @code{float} step=@code{1.f}, @code{bool} as_slice=@code{false})
+@end ifclear
 Объединяет данные из нескольких текстовых файлов. Имена файлов определяются вызовом функции @code{sprintf(fname,templ,val);}, где @var{val} меняется от @var{from} до @var{to} с шагом @var{step}. Данные загружаются один за другим в один и тот же срез данных (при @var{as_slice}=@code{false}) или срез-за-срезом (при @var{as_slice}=@code{true}).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
+@deftypefn {MGL command} {} readall @sc{dat} 'templ' @code{[slice=off]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
+@end ifclear
 Объединяет данные из нескольких текстовых файлов, чьи имена удовлетворяют шаблону @var{templ} (например, @var{templ}=@code{"t_*.dat"}). Данные загружаются один за другим в один и тот же срез данных (при @var{as_slice}=@code{false}) или срез-за-срезом (при @var{as_slice}=@code{true}).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
-@deftypefnx {Функция С} @code{void} mgl_data_save (@code{const HMDT} dat, @code{const char *}fname, @code{int} ns)
+@anchor{save}
+@deftypefn {MGL command} {} save dat 'fname'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
+@deftypefnx {C function} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
+@end ifclear
 Сохраняет весь массив данных при @var{ns}=@code{-1} или только @var{ns}-ый срез в текстовый файл.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
+@anchor{readhdf}
+@deftypefn {MGL command} {} readhdf @sc{dat} 'fname' 'dname'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
+@deftypefnx {C function} @code{void} mgl_data_read_hdf (@code{HMDT} dat, @code{const char *}fname, @code{const char *}dname)
+@end ifclear
 Читает массив с именем @var{dname} из HDF5 или HDF4 файла @var{fname}. Функция ничего не делает если библиотека была собрана с флагами NO_HDF5|NO_HDF4.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
+
+@anchor{savehdf}
+@deftypefn {MGL command} {} savehdf dat 'fname' 'dname'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
+@deftypefnx {C function} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
+@end ifclear
 Сохраняет массив под именем @var{dname} в HDF5 или HDF4 файл @var{fname}. Функция ничего не делает если библиотека была собрана с флагами NO_HDF5|NO_HDF4.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Import (@code{const char *}fname, @code{const char *}scheme, @code{float} v1=@code{0}, float v2=@code{1})
-@deftypefnx {Функция С} @code{void} mgl_data_import (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{float} v1, float v2)
+@anchor{datas}
+@deftypefn {MGL command} {} datas 'fname'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{const}
+@deftypefnx {C function} @code{void} mgl_datas_hdf (@code{const char *}fname, @code{char *}buf, @code{long} size)
+@end ifclear
+Помещает имена массивов данных в HDF5 файле @var{fname} в строку @var{buf} разделёнными символом табуляции '\t'. В версии MGL имена массивов будут выведены как сообщение. Функция ничего не делает если библиотека была собрана с флагом NO_HDF5.
+@end deftypefn
+
+@anchor{import}
+@deftypefn {MGL command} {} import @sc{dat} 'fname' 'sch' [@code{v1=0 v2=1}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Import (@code{const char *}fname, @code{const char *}scheme, @code{float} v1=@code{0}, float v2=@code{1})
+@deftypefnx {C function} @code{void} mgl_data_import (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{float} v1, float v2)
+@end ifclear
 Читает данные из растрового файла. RGB значения пикселов преобразуются в число в диапазоне [@var{v1}, @var{v2}] используя цветовую схему @var{sch} (@pxref{Color scheme}).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{float} v1=@code{0}, float v2=@code{0}, @code{int} ns=@code{-1}) const
-@deftypefnx {Функция С} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{float} v1, float v2, @code{int} ns) const
+@anchor{export}
+@deftypefn {MGL command} {} export dat 'fname' 'sch' [@code{v1=0 v2=0}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{float} v1=@code{0}, float v2=@code{0}, @code{int} ns=@code{-1}) const
+@deftypefnx {C function} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{float} v1, float v2, @code{int} ns) const
+@end ifclear
 Сохраняет данные в растровый файл. Числовые значения, нормированные в диапазон [@var{v1}, @var{v2}], преобразуются в RGB значения пикселов, используя цветовую схему @var{sch} (@pxref{Color scheme}). Если @var{v1}>=@var{v2}, то значения @var{v1}, @var{v2} определяются автоматически как минимальное и максимальное значение данных.
 @end deftypefn
 
+
 @c ------------------------------------------------------------------
-@node Make another data, Change data, File I/O, Data processing
-@section Создание новых данных
+@node Make another data, Data changing, File I/O, Data processing
+@section Make another data
 @cindex SubData
 @cindex Column
-@cindex SetColumnId
+@cindex Trace
 @cindex Hist
+@cindex Resize
+@cindex Evaluate
+@cindex Combine
 @cindex Momentum
 @cindex Sum
-@cindex Max
 @cindex Min
-@cindex Combine
-@cindex Evaluate
-@cindex Resize
-@cindex Trace
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} SubData (@code{int} xx, @code{int} yy=@code{-1}, @code{int} zz=@code{-1}) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_subdata (@code{const HMDT} dat, @code{int} xx, @code{int} yy, @code{int} zz)
-Возвращает в @var{res} подмассив массива данных @var{dat} с фиксированными значениями индексов с положительными значениями. Например, @code{SubData(-1,2)} выделяет третью строку (индексы начинаются с нуля), @code{SubData(4,-1)} выделяет 5-ую колонку, @code{SubData(-1,-1,3)} выделяет 4-ый срез и т.д.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} SubData (@code{const mglData &}xx, @code{const mglData &}yy, @code{const mglData &}zz) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_subdata_ext (@code{const HMDT} dat, @code{const HMDT} xx, @code{const HMDT} yy, @code{const HMDT} zz)
-Extracts sub-array data from the original data array for indexes specified by arrays @var{xx}, @var{yy}, @var{zz} (indirect access). The resulting array have the same dimensions as input arrays for 2D and 3D arguments. This function work like previous one for 1D arguments (or numbers). The dimensions of all argument must be the same if they are 2D or 3D arrays.
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Column (@code{const char *}eq) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_column (@code{const HMDT} dat, @code{const char *}eq)
-Возвращает массив данных заполненный по формуле @var{eq}, вычисленной для именованных колонок (или срезов). Например, @code{Column("n*w^2/exp(t)");}. Имена колонок задается функцией @code{SetColumnId()} или при чтении файлов данных.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} SetColumnId (@code{const char *}ids)
-@deftypefnx {Функция С} @code{void} mgl_data_set_id (@code{HMDT} dat, @code{const char *}ids)
-Устанавливает символьные обозначения для колонок данных. Строка должна содержать символы 'a'...'z' один на колонку (без пробелов).
-@end deftypefn
-
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Trace () @code{const}
-Возвращает массив диагональных элементов a[i,i] (для 2D данных) или a[i,i,i] (для 3D данных) где i=0...nx-1. В 1D случае возвращается сам массив данных. Размеры массива данных должен быть ny,nz >= nx или ny,nz = 1.
-@end deftypefn
+@cindex Max
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Hist (@code{int} n, @code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_hist (@code{const HMDT} dat, @code{int} n, @code{float} v1, @code{float} v2, @code{int} nsub)
-Возвращает распределение (гистограмму) из @var{n} точек от значений массива в диапазоне [@var{v1}, @var{v2}]. Параметр @var{nsub} задает число дополнительных точек интерполяции (для сглаживания получившейся гистограммы).
+@anchor{subdata}
+@deftypefn {MGL command} {} subdata @sc{res} dat @code{xx [yy=: zz=:]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{float} xx, @code{float} yy=@code{-1}, @code{float} zz=@code{-1}) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_subdata (@code{HCDT} dat, @code{float} xx, @code{float} yy, @code{float} zz)
+@end ifclear
+Возвращает в @var{res} подмассив массива данных @var{dat} с фиксированными значениями индексов с положительными значениями. Например, @code{SubData(-1,2)} выделяет третью строку (индексы начинаются с нуля), @code{SubData(4,-1)} выделяет 5-ую колонку, @code{SubData(-1,-1,3)} выделяет 4-ый срез и т.д. В MGL скриптах обычно используется упрощенная версия @code{dat(xx,yy,zz)}.
+@end deftypefn
+
+@deftypefn {MGL command} {} subdata @sc{res} dat xdat [ydat=: zdat=:]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglData &}xx, @code{const mglData &}yy, @code{const mglData &}zz) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
+@end ifclear
+Возвращает в @var{res} подмассив массива данных @var{dat} с индексами, заданными в массивах @var{xx}, @var{yy}, @var{zz} (косвенная адресация). Результат будет иметь размерность массивов с индексами. Размеры массивов @var{xx}, @var{yy}, @var{zz} с индексами должна быть одинакова, либо должны быть "скаляром" (т.е. 1*1*1). В MGL скриптах обычно используется упрощенная версия @code{dat(xx,yy,zz)}.
+@end deftypefn
+
+@anchor{column}
+@deftypefn {MGL command} {} column @sc{res} dat 'eq'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Column (@code{const char *}eq) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_column (@code{HCDT} dat, @code{const char *}eq)
+@end ifclear
+Возвращает массив данных заполненный по формуле @var{eq}, вычисленной для именованных колонок (или срезов). Например, @code{Column("n*w^2/exp(t)");}. Имена колонок должны быть предварительно заданы функцией @ref{idset} или при чтении файлов данных. В MGL скриптах обычно используется упрощенная версия @code{dat('eq')}.
+@end deftypefn
+
+@anchor{resize}
+@deftypefn {MGL command} {} resize @sc{res} dat @code{mx [my=1 mz=1]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1}, @code{float} x1=@code{0}, @code{float} x2=@code{1}, @code{float} y1=@code{0}, @code{float} y2=@code{1}, @code{float} z1=@code{0}, @code{float} z2=@code{1}) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_resize (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
+@deftypefnx {C function} @code{HMDT} mgl_data_resize_box (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz, @code{float} x1, @code{float} x2, @code{float} y1, @code{float} y2, @code{float} z1, @code{float} z2)
+@end ifclear
+Возвращает массив данных размером @var{mx}, @var{my}, @var{mz} со значениями полученными интерполяцией значений из части [@var{x1},@var{x2}] x [@var{y1},@var{y2}] x [@var{z1},@var{z2}] исходного массива. Величины x,y,z полагаются нормированными в диапазоне [0,1].
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Hist (@code{const mglData &}w, @code{int} n, @code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_hist_w (@code{const HMDT} dat, @code{const HMDT} w, @code{int} n, @code{float} v1, @code{float} v2, @code{int} nsub)
-Возвращает распределение (гистограмму) из @var{n} точек от значений массива в диапазоне [@var{v1}, @var{v2}]. Массив @var{w} задает веса элементов. Параметр @var{nsub} задает число дополнительных точек интерполяции (для сглаживания получившейся гистограммы).
+@anchor{evaluate}
+@deftypefn {MGL command} {} evaluate @sc{res} dat idat [@code{norm=on}]
+@deftypefnx {MGL command} {} evaluate @sc{res} dat idat jdat [@code{norm=on}]
+@deftypefnx {MGL command} {} evaluate @sc{res} dat idat jdat kdat [@code{norm=on}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglData &}idat, @code{bool} norm=@code{true}) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglData &}idat, @code{const mglData &}jdat, @code{bool} norm=@code{true}) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglData &}idat, @code{const mglData &}jdat, @code{const mglData &}kdat, @code{bool} norm=@code{true}) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_evaluate (@code{HCDT} dat, @code{HCDT} idat, @code{HCDT} jdat, @code{HCDT} kdat, @code{int} norm)
+@end ifclear
+Возвращает массив данных, полученный в результате интерполяции исходного массива в точках других массивов (например, res[i,j]=dat[idat[i,j],jdat[i,j]]). Размеры массивов @var{idat}, @var{jdat}, @var{kdat} должны совпадать. Координаты в @var{idat}, @var{jdat}, @var{kdat} полагаются нормированными в диапазон [0,1] (при @var{norm}=@code{true}) или в диапазоны [0,nx], [0,ny], [0,nz] соответственно.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_momentum (@code{const HMDT} dat, @code{char} dir, @code{const char *}how)
+@anchor{hist}
+@deftypefn {MGL command} {} hist @sc{res} dat @code{num v1 v2 [nsub=0]}
+@deftypefnx {MGL command} {} hist @sc{res} dat wdat @code{num v1 v2 [nsub=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Hist (@code{int} n, @code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{mglData} Hist (@code{const mglData &}w, @code{int} n, @code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_hist (@code{HCDT} dat, @code{int} n, @code{float} v1, @code{float} v2, @code{int} nsub)
+@deftypefnx {C function} @code{HMDT} mgl_data_hist_w (@code{HCDT} dat, @code{HCDT} w, @code{int} n, @code{float} v1, @code{float} v2, @code{int} nsub)
+@end ifclear
+Возвращает распределение (гистограмму) из @var{n} точек от значений массива в диапазоне [@var{v1}, @var{v2}]. Массив @var{w} задает веса элементов (по умолчанию все веса равны 1). Параметр @var{nsub} задает число дополнительных точек интерполяции (для сглаживания получившейся гистограммы). См. также @ref{Data manipulation}
+@end deftypefn
+
+@anchor{momentum}
+@deftypefn {MGL command} {} momentum @sc{res} dat 'how' ['dir'='z']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_momentum (@code{HCDT} dat, @code{char} dir, @code{const char *}how)
+@end ifclear
 Возвращает момент (1d массив) данных вдоль направления @var{dir}. Строка @var{how} определяет тип момента. Момент определяется как
 @iftex
 @math{res_k = \sum_{ij} how(x_i,y_j,z_k) a_{ij}/\sum_{ij} a_{ij}}
@@ -364,144 +588,211 @@ res_k = \sum_ij how(x_i,y_j,z_k) a_ij/ \sum_ij a_ij
 если @var{dir}=@samp{z} и т.д. Координаты @samp{x}, @samp{y}, @samp{z} -- индексы массива в диапазоне [0,1].
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Sum (@code{const char *}dir) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_sum (@code{const HMDT} dat, @code{const char *}dir)
+@anchor{sum}
+@deftypefn {MGL command} {} sum @sc{res} dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Sum (@code{const char *}dir) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_sum (@code{HCDT} dat, @code{const char *}dir)
+@end ifclear
 Возвращает результат суммирования данных вдоль направления(ий) @var{dir}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Max (@code{const char *}dir) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_max_dir (@code{const HMDT} dat, @code{const char *}dir)
+@anchor{max}
+@deftypefn {MGL command} {} max @sc{res} dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Max (@code{const char *}dir) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_max_dir (@code{HCDT} dat, @code{const char *}dir)
+@end ifclear
 Возвращает максимальное значение данных вдоль направления(ий) @var{dir}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Min (@code{const char *}dir) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_min_dir (@code{const HMDT} dat, @code{const char *}dir)
+@anchor{min}
+@deftypefn {MGL command} {} min @sc{res} dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Min (@code{const char *}dir) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_min_dir (@code{HCDT} dat, @code{const char *}dir)
+@end ifclear
 Возвращает минимальное значение данных вдоль направления(ий) @var{dir}.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Combine (@code{const mglData &}a) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_combine (@code{const HMDT} dat, @code{const HMDT} a)
+@anchor{combine}
+@deftypefn {MGL command} {} combine @sc{res} adat bdat
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Combine (@code{const mglData &}a) @code{const}
+@deftypefnx {C function} @code{HMDT} mgl_data_combine (@code{HCDT} dat, @code{HCDT} a)
+@end ifclear
 Возвращает прямое произведение массивов (наподобие, res[i,j] = adat[i]*bdat[j] и т.д.).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Evaluate (@code{const mglData &}idat, @code{bool} norm=@code{true}) @code{const}
-@deftypefnx {Метод класса @code{mglData} (C++, Python)} @code{mglData} Evaluate (@code{const mglData &}idat, @code{const mglData &}jdat, @code{bool} norm=@code{true}) @code{const}
-@deftypefnx {Метод класса @code{mglData} (C++, Python)} @code{mglData} Evaluate (@code{const mglData &}idat, @code{const mglData &}jdat, @code{const mglData &}kdat, @code{bool} norm=@code{true}) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_evaluate_i (@code{const HMDT} dat, @code{const HMDT} idat, @code{int} norm)
-@deftypefnx {Функция С} @code{HMDT} mgl_data_evaluate_ij (@code{const HMDT} dat, @code{const HMDT} idat, @code{const HMDT} jdat, @code{int} norm)
-@deftypefnx {Функция С} @code{HMDT} mgl_data_evaluate_ijk (@code{const HMDT} dat, @code{const HMDT} idat, @code{const HMDT} jdat, @code{const HMDT} kdat, @code{int} norm)
-Возвращает массив данных, полученный в результате интерполяции исходного массива в точках других массивов (например, res[i,j]=dat[idat[i,j],jdat[i,j]]). Размеры массивов @var{idat}, @var{jdat}, @var{kdat} должны совпадать. Координаты в @var{idat}, @var{jdat}, @var{kdat} полагаются нормированными в диапазон [0,1] (при @var{norm}=@code{true}) или в диапазоны [0,nx], [0,ny], [0,nz] соответственно.
+@anchor{trace}
+@deftypefn {MGL command} {} trace @sc{res} dat
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{mglData} Trace () @code{const}
+@end ifclear
+Возвращает массив диагональных элементов a[i,i] (для 2D данных) или a[i,i,i] (для 3D данных) где i=0...nx-1. В 1D случае возвращается сам массив данных. Размеры массива данных должен быть ny,nz >= nx или ny,nz = 1.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1}, @code{float} x1=@code{0}, @code{float} x2=@code{1}, @code{float} y1=@code{0}, @code{float} y2=@code{1}, @code{float} z1=@code{0}, @code{float} z2=@code{1}) @code{const}
-@deftypefnx {Функция С} @code{HMDT} mgl_data_resize (@code{const HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
-@deftypefnx {Функция С} @code{HMDT} mgl_data_resize_box (@code{const HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz, @code{float} x1, @code{float} x2, @code{float} y1, @code{float} y2, @code{float} z1, @code{float} z2)
-Возвращает массив данных размером @var{mx}, @var{my}, @var{mz} со значениями полученными интерполяцией значений из части [@var{x1},@var{x2}] x [@var{y1},@var{y2}] x [@var{z1},@var{z2}] исходного массива. Величины x,y,z полагаются нормированными в диапазоне [0,1].
-@end deftypefn
 
 @c ------------------------------------------------------------------
-@node Change data, Interpolation, Make another data, Data processing
+@node Data changing, Interpolation, Make another data, Data processing
 @section Изменение данных
+@cindex CumSum
+@cindex Integral
+@cindex Diff
+@cindex Diff2
+@cindex SinFFT
+@cindex CosFFT
+@cindex Hankel
+@cindex Swap
+@cindex Roll
+@cindex Mirror
+@cindex Sew
+@cindex Smooth
+@cindex Envelop
+@cindex Norm
+@cindex NormSl
 
-Эти функции изменяют данные вдоль заданного направления(ий) типа например дифференцирования, интегрирования и т.д. Направление указывается строкой @var{dir}, которая может содержать символы @samp{x}, @samp{y} и/или @samp{z}, вдоль которых изменения будут применены.
+These functions change the data in some direction like differentiations, integrations and so on. The direction in which the change will applied is specified by the string parameter, which may contain @samp{x}, @samp{y} or @samp{z} characters for 1-st, 2-nd and 3-d dimension correspondengly.
 
-@cindex CumSum
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} CumSum (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_cumsum (@code{HMDT} dat, @code{const char *}dir)
+@anchor{cumsum}
+@deftypefn {MGL command} {} cumsum dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} CumSum (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_cumsum (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Суммирует с накоплением в выбранном направлении(ях).
 @end deftypefn
 
-@cindex Integral
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Integral (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_integral (@code{HMDT} dat, @code{const char *}dir)
-Выполняет интегрирование (подобно суммированию с накоплением) в выбранном направлении(ях).
+@anchor{integrate}
+@deftypefn {MGL command} {} integrate dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Integral (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_integral (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
+Выполняет интегрирование (методом трапеций) в выбранном направлении(ях).
 @end deftypefn
 
-@cindex Diff
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Diff (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_diff (@code{HMDT} dat, @code{const char *}dir)
+@anchor{diff}
+@deftypefn {MGL command} {} diff dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_diff (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Выполняет дифференцирование в выбранном направлении(ях).
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Diff (@code{const mglData &}x, @code{const mglData &}y)
-@deftypefnx {Метод класса @code{mglData} (C++, Python)} @code{void} Diff (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z)
-@deftypefnx {Функция С} @code{void} mgl_data_diff_par (@code{HMDT} dat, @code{const HMDT} x, @code{const HMDT}y, @code{const HMDT}z)
+@deftypefn {MGL command} {} diff dat xdat ydat [zdat=0]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const mglData &}x, @code{const mglData &}y)
+@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z)
+@deftypefnx {C function} @code{void} mgl_data_diff_par (@code{HMDT} dat, @code{HCDT} x, @code{HCDT}y, @code{HCDT}z)
+@end ifclear
 Выполняет дифференцирование данных, параметрически зависящих от координат, в направлении @var{x} с @var{y}, @var{z}=constant. Параметр @var{z} может быть опущен, что соответствует 2D случаю. Используются следующие формулы (2D случай): @math{da/dx = (a_j*y_i-a_i*y_j)/(x_j*y_i-x_i*y_j)}, где @math{a_i=da/di, a_j=da/dj} обозначает дифференцирование вдоль 1-ой и 2-ой размерности. Похожие формулы используются и в 3D случае. Порядок аргументов можно менять -- например, если данные a(i,j) зависят от координат @{x(i,j), y(i,j)@}, то обычная производная по @samp{x} будет равна @code{Diff(x,y);}, а обычная производная по @samp{y} будет равна @code{Diff(y,x);}.
 @end deftypefn
 
-
-@cindex Diff2
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Diff2 (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_diff2 (@code{const char *}dir)
+@anchor{diff2}
+@deftypefn {MGL command} {} diff2 dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Diff2 (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_diff2 (@code{const char *}dir)
+@end ifclear
 Выполняет двойное дифференцирование (как в операторе Лапласа) в выбранном направлении(ях).
 @end deftypefn
 
-@cindex SinFFT
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} SinFFT (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_sinfft (@code{HMDT} dat, @code{const char *}dir)
+@anchor{sinfft}
+@deftypefn {MGL command} {} sinfft dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} SinFFT (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_sinfft (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Выполняет синус преобразование в выбранном направлении(ях). Синус преобразование есть @math{\sum a_i \sin(k i)}.
 @end deftypefn
 
-@cindex CosFFT
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} CosFFT (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_cosfft (@code{HMDT} dat, @code{const char *}dir)
+@anchor{cosfft}
+@deftypefn {MGL command} {} cosfft dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} CosFFT (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_cosfft (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Выполняет косинус преобразование в выбранном направлении(ях). Синус преобразование есть @math{\sum a_i \cos(k i)}.
 @end deftypefn
 
-@cindex Hankel
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Hankel (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_hankel (@code{HMDT} dat, @code{const char *}dir)
+@anchor{hankel}
+@deftypefn {MGL command} {} hankel dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Hankel (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_hankel (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Выполняет преобразование Ханкеля в выбранном направлении(ях). Преобразование Ханкеля есть @math{\sum a_i J_0(k i)}.
 @end deftypefn
 
-
-@cindex Swap
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Swap (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_swap (@code{HMDT} dat, @code{const char *}dir)
+@anchor{swap}
+@deftypefn {MGL command} {} swap dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Swap (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_swap (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
 Меняет местами левую и правую части данных в выбранном направлении(ях). Полезно для отображения результата FFT.
 @end deftypefn
 
-@cindex Roll
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Roll (@code{char} dir, @code{num})
-@deftypefnx {Функция С} @code{void} mgl_data_roll (@code{HMDT} dat, @code{char} dir, @code{num})
-Сдвигает данные на @var{num} ячеек в выбранном направлении(ях). Соответствует замене индекса на @var{i}->(@var{i}+@var{num})%@var{n}.
+@anchor{roll}
+@deftypefn {MGL command} {} roll dat 'dir' num
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Roll (@code{char} dir, @code{num})
+@deftypefnx {C function} @code{void} mgl_data_roll (@code{HMDT} dat, @code{char} dir, @code{num})
+@end ifclearСдвигает данные на @var{num} ячеек в выбранном направлении(ях). Соответствует замене индекса на @var{i}->(@var{i}+@var{num})%@var{n}  при @code{dir='x'}.
 @end deftypefn
 
-@cindex Mirror
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Mirror (@code{const char *}dir)
-@deftypefnx {Функция С} @code{void} mgl_data_mirror (@code{HMDT} dat, @code{const char *}dir)
-Отражает данные в выбранном направлении(ях). Соответствует замене индекса на @var{i}->@var{n}-@var{i}.
+@anchor{mirror}
+@deftypefn {MGL command} {} mirror dat 'dir'
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Mirror (@code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_mirror (@code{HMDT} dat, @code{const char *}dir)
+@end ifclear
+Отражает данные в выбранном направлении(ях). Соответствует замене индекса на @var{i}->@var{n}-@var{i}. Отмечу, что похожего эффекта на графике можно достичь используя опции (@pxref{Command options}), например, @code{surf dat; xrange 1 -1}.
 @end deftypefn
 
-@cindex Sew
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Sew (@code{const char *}dir, @code{float} da=@code{2*M_PI})
-@deftypefnx {Функция С} @code{void} mgl_data_sew (@code{HMDT} dat, @code{const char *}dir, @code{float} da)
+@anchor{sew}
+@deftypefn {MGL command} {} sew dat ['dir'='xyz' @code{da=2*pi}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Sew (@code{const char *}dir, @code{float} da=@code{2*M_PI})
+@deftypefnx {C function} @code{void} mgl_data_sew (@code{HMDT} dat, @code{const char *}dir, @code{float} da)
+@end ifclear
 Удаляет скачки данных (например, скачки фазы после обратных тригонометрических функций) с периодом @var{da} в выбранном направлении(ях).
 @end deftypefn
 
-@cindex Smooth
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Smooth (@code{int} Type, @code{const char *}dir, @code{float} delta=@code{0})
-@deftypefnx {Функция С} @code{void} mgl_data_smooth (@code{HMDT} dat, @code{int} Type, @code{float} delt, @code{const char *}dirs)
-Сглаживает данные в выбранном направлении(ях) @var{dir} методом @var{Type}. Сейчас поддерживаются 4 метода: @code{SMOOTH_NONE=0} ничего не делает при @var{delta}=0 или сдвигает данные к нулю на шагом @var{delta}, @code{SMOOTH_LINE_3=1} линейное усреднение по 3 точкам, @code{SMOOTH_LINE_5=2} линейное усреднение по 5 точкам, @code{SMOOTH_QUAD_5=3} квадратичное усреднение по 5 точкам. Параметр @var{delta} запрещает изменение значений на величину большую @var{delta}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Smooth (@code{const char *}dir)
-Smooths the data on specified direction(s). This is the same as @code{Smooth()} but argument @var{Type} is specified in string as @samp{0} for @code{SMOOTH_NONE}, @samp{3} for @code{SMOOTH_LINE_3}, @samp{5} for @code{SMOOTH_LINE_5}. If string @var{dir} don't contain digits @samp{035} then @var{Type}=@code{SMOOTH_QUAD_5} is used.
+@anchor{smooth}
+@deftypefn {MGL command} {} smooth data @code{type} ['dir'='xyz']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{float} delta=@code{0})
+@deftypefnx {C function} @code{void} mgl_data_smooth (@code{HMDT} dat, @code{const char *}dir, @code{float} delta)
+@end ifclear
+Сглаживает данные в выбранном направлении(ях) @var{dir}. Строка @var{dirs} задает направления вдоль которых будет производиться сглаживание. Если @var{dirs} содержит: @samp{0} -- ничего не делает, @samp{3} линейное усреднение по 3 точкам, @samp{5} линейное усреднение по 5 точкам. По умолчанию используется квадратичное усреднение по 5 точкам.
 @end deftypefn
 
-@cindex Envelop
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Envelop (@code{char} dir=@code{'x'})
-@deftypefnx {Функция С} @code{void} mgl_data_envelop (@code{HMDT} dat, @code{char} dir)
+@anchor{envelop}
+@deftypefn {MGL command} {} envelop dat ['dir'='x']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Envelop (@code{char} dir=@code{'x'})
+@deftypefnx {C function} @code{void} mgl_data_envelop (@code{HMDT} dat, @code{char} dir)
+@end ifclear
 Находит огибающую данных в выбранном направлении @var{dir}.
 @end deftypefn
 
-@cindex Norm
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} Norm (@code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{bool} sym=@code{false}, @code{int} dim=@code{0})
+@anchor{norm}
+@deftypefn {MGL command} {} norm dat @code{v1 v2 [sym=off dim=0]}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} Norm (@code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{bool} sym=@code{false}, @code{int} dim=@code{0})
+@end ifclear
 Нормирует данные в интервал [@var{v1},@var{v2}]. Если @var{sym}=@code{true}, то используется симметричный интервал [-max(|v1|,|v2|), max(|v1|,|v2|)]. Изменения применяются только к срезам >=@var{dim}.
 @end deftypefn
 
-@cindex NormSl
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} NormSl (@code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{char} dir=@code{'z'}, @code{bool} keep_en=@code{true}, @code{bool} sym=@code{false})
-@deftypefnx {Функция С} @code{void} mgl_data_norm_slice (@code{HMDT} dat, @code{float} v1, @code{float} v2, @code{char} dir, @code{int} keep_en, @code{int} sym)
+@anchor{normsl}
+@deftypefn {MGL command} {} normsl dat @code{v1 v2} ['dir'='z' @code{keep=on sym=off}]
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} NormSl (@code{float} v1=@code{0}, @code{float} v2=@code{1}, @code{char} dir=@code{'z'}, @code{bool} keep_en=@code{true}, @code{bool} sym=@code{false})
+@deftypefnx {C function} @code{void} mgl_data_norm_slice (@code{HMDT} dat, @code{float} v1, @code{float} v2, @code{char} dir, @code{int} keep_en, @code{int} sym)
+@end ifclear
 Нормирует данные срез-за-срезом в выбранном направлении @var{dir} в интервал [@var{v1},@var{v2}]. Если @var{sym}=@code{true}, то используется симметричный интервал [-max(|v1|,|v2|), max(|v1|,|v2|)]. Если @var{keep}=@code{true}, то максимальное значение k-го среза ограничено величиной
 @iftex
 @math{\sqrt{\sum a_{ij}(k)/\sum a_{ij}(0)}}.
@@ -511,227 +802,424 @@ Smooths the data on specified direction(s). This is the same as @code{Smooth()}
 @end ifnottex
 @end deftypefn
 
+
 @c ------------------------------------------------------------------
-@node Interpolation, Informational functions, Change data, Data processing
+@node Interpolation, Data information, Data changing, Data processing
 @section Интерполяция
+
+Скрипты MGL могут использовать линейную интерполяцию с помощью команды @ref{subdata}, или кубические сплайны при использовании команды @ref{evaluate}. Также можно использовать @ref{resize} для массива с новыми размерами.
+
+@ifclear UDAV
+
+Однако, есть специальные и более быстрые функции при использовании других языков (C/C++/Fortran/Python/...).
+
 @cindex Spline
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} Spline (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
-@deftypefnx {C function} @code{float} mgl_data_spline (@code{const HMDT} dat, @code{float} x, @code{float} y, @code{float} z)
+@deftypefn {Method on @code{mglData}} @code{float} Spline (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_spline (@code{HCDT} dat, @code{float} x, @code{float} y, @code{float} z)
 Интерполирует данные кубическим сплайном в точке @var{x} в [0...nx-1], @var{y} в [0...ny-1], @var{z} в [0...nz-1].
 @end deftypefn
 @cindex Spline1
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} Spline1 (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
-@deftypefnx {C function} @code{float} mgl_data_spline1 (@code{const HMDT} dat, @code{float} x, @code{float} y, @code{float} z)
+@deftypefn {Method on @code{mglData}} @code{float} Spline1 (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
 Интерполирует данные кубическим сплайном в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1].
 @end deftypefn
 @cindex Linear
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} Linear (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
-@deftypefnx {C function} @code{float} mgl_data_linear (@code{const HMDT} dat, @code{float} x, @code{float} y, @code{float} z)
+@deftypefn {Method on @code{mglData}} @code{float} Linear (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_linear (@code{HCDT} dat, @code{float} x, @code{float} y, @code{float} z)
 Интерполирует данные линейной функцией в точке @var{x} в [0...nx-1], @var{y} в [0...ny-1], @var{z} в [0...nz-1].
 @end deftypefn
 @cindex Linear1
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} Linear1 (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
-@deftypefnx {C function} @code{float} mgl_data_linear1 (@code{const HMDT} dat, @code{float} x, @code{float} y, @code{float} z)
+@deftypefn {Method on @code{mglData}} @code{float} Linear1 (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}) @code{const}
 Интерполирует данные линейной функцией в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1].
 @end deftypefn
-@cindex v
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} v (@code{int} i, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
-@deftypefnx {C function} @code{float} mgl_data_get_value (@code{const HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
-Возвращает значение ячейки с проверкой на границы массива данных.
-@end deftypefn
-@cindex Spline5
-@deftypefn {Method on @code{mglData} (C++, Python)} @code{float} Spline5 (@code{float} x, @code{float} y, @code{float} z, @code{float} &dx, @code{float} &dy, @code{float} &dz) @code{const}
-Интерполирует данные сплайном 5-го порядка в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1].
-@end deftypefn
 
-@deftypefn {C function} @code{float *} mgl_data_value (@code{HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
-Возвращает указатель на ячейку данных. Может быть не действителен после вызова любой функции изменяющей данные.
-@end deftypefn
-@deftypefn {C function} @code{const float *} mgl_data_data (@code{const HMDT} dat)
-Возвращает указатель на весь массив данных. Может быть не действителен после вызова любой функции изменяющей данные.
-@end deftypefn
+@end ifclear
+
 
 @c ------------------------------------------------------------------
-@node Informational functions, Operators, Interpolation, Data processing
+@node Data information, Operators, Interpolation, Data processing
 @section Информационные функции
+
+В MathGL есть ряд функций для получения свойств массива данных. В MGL скриптах большинство из них реализовано в виде "суффиксов". Суффиксы дают числовое значение некоторой характеристики массива данных. Например, его размер, минимальное и максимальное значение, сумму элементов и т.д. Суффиксы начинаются с точки @samp{.} сразу после массива (без пробелов). Например, @code{a.nx} даст размер массива @var{a} вдоль x, @code{b(1).max} даст максимальное значение второй колонки массива @var{b}, @code{(c(:,0)^2).sum} даст сумму квадратов в первой строке массива @var{c} и т.д.
+
+
 @cindex PrintInfo
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} PrintInfo (@code{char *}buf, @code{bool} all=@code{false}) @code{const}
-Печатает информацию о данных (размеры, моменты и пр.) в строку @var{buf}. Параметр @var{all} устанавливает печатать ли подробную информацию (если @code{true}) или только базовую информацию.
+
+@anchor{info}
+@deftypefn {MGL command} {} info dat
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{const char *} PrintInfo () @code{const}
+@deftypefnx {Method on @code{mglData}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
+@deftypefnx {C function} @code{const char *} mgl_data_info (@code{HCDT} dat)
+@end ifclear
+Возвращает строку с информацией о данных (размеры, моменты и пр.) или пишет её в файл. В MGL скрипте печатает её как сообщение.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++)} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
-Аналогично, но выводит в файл (или, например, в stdout).
+
+@deftypefn {MGL command} {} info 'txt'
+Печатает строку @var{txt} как сообщение.
+@end deftypefn
+
+@cindex GetNx
+@cindex GetNy
+@cindex GetNz
+@anchor{.nx} @anchor{.ny} @anchor{.nz}
+@deftypefn {MGL suffix} {(dat)} .nx
+@deftypefnx {MGL suffix} {(dat)} .ny
+@deftypefnx {MGL suffix} {(dat)} .nz
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{long} GetNx ()
+@deftypefnx {Method on @code{mglData}} @code{long} GetNy ()
+@deftypefnx {Method on @code{mglData}} @code{long} GetNz ()
+@deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
+@deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
+@deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
+@end ifclear
+Возвращает размер данных в направлении x, y и z соответственно.
 @end deftypefn
 
+
+
 @cindex Maximal
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Maximal () @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_max (@code{const HMDT} dat)
+@anchor{.max}
+@deftypefn {MGL suffix} {(dat)} .max
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{float} Maximal () @code{const}
+@deftypefnx {C function} @code{float} mgl_data_max (@code{HCDT} dat)
+@end ifclear
 Возвращает максимальное значение массива данных.
 @end deftypefn
+
 @cindex Minimal
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Minimal () @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_min (@code{HMDT} dat) @code{const}
+@anchor{.min}
+@deftypefn {MGL suffix} {(dat)} .min
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{float} Minimal () @code{const}
+@deftypefnx {C function} @code{float} mgl_data_min (@code{HMDT} dat) @code{const}
+@end ifclear
 Возвращает минимальное значение массива данных.
 @end deftypefn
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_max_int (@code{const HMDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
-Возвращает максимальное значение массива данных и его положение в переменные @var{i}, @var{j}, @var{k}.
+@ifclear UDAV
+@deftypefn {Method on @code{mglData}} @code{float} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_min_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
+Возвращает максимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_min_int (@code{const HMDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
-Возвращает минимальное значение массива данных и его положение в переменные @var{i}, @var{j}, @var{k}.
+@deftypefn {Method on @code{mglData}} @code{float} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
+Возвращает минимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Maximal (@code{float} &i, @code{float} &j, @code{float} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_max_real (@code{const HMDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
-Возвращает максимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{i}, @var{j}, @var{k}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Minimal (@code{float} &i, @code{float} &j, @code{float} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_min_real (@code{const HMDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
-Возвращает минимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{i}, @var{j}, @var{k}.
+@deftypefn {Method on @code{mglData}} @code{float} Minimal (@code{float} &x, @code{float} &y, @code{float} &z) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_min_real (@code{HCDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
+Возвращает максимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
 @end deftypefn
+@end ifclear
 
-@cindex Momentum
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Momentum (@code{char} dir, @code{float} &m, @code{float} &w) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_momentum_mw (@code{const HMDT} dat, @code{char} dir, @code{float} *m, @code{float} *w)
-Возвращает нулевой момент (энергию, @math{I=\sum a_i}) и записывает первый (среднее, @math{m = \sum \xi_i a_i/I}) и второй момент (ширину, @math{w^2 = \sum (\xi_i-m)^2 a_i/I}). Здесь @math{\xi} -- соответствующая кордината если @var{dir} равно @samp{'x'}, @samp{'y'}, @samp{'z'}. В противном случае среднее и ширина равны @math{m = \sum a_i/N}, @math{w^2 = \sum (a_i-m)^2/N}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++)} @code{float} Momentum (@code{char} dir, @code{float} &m, @code{float} &w, @code{float} &s, @code{float} &k) @code{const}
-Возвращает нулевой момент (энергию, @math{I=\sum a_i}) и записывает первый (среднее, @math{m = \sum \xi_i a_i/I}), второй (ширину, @math{w^2 = \sum (\xi_i-m)^2 a_i/I}), третий (асимметрия, @math{s = \sum (\xi_i-m)^3 a_i/ I w^3}) и четвертый моменты (эксцесс, @math{k = \sum (\xi_i-m)^4 a_i / 3 I w^4})). Здесь @math{\xi} -- соответствующая кордината если @var{dir} равно @samp{'x'}, @samp{'y'}, @samp{'z'}. В противном случае среднее, ширина, асимметрия, эксцесс равны @math{m = \sum a_i/N}, @math{w^2 = \sum (a_i-m)^2/N} и т.д.
+@anchor{.mx} @anchor{.my} @anchor{.mz}
+@deftypefn {MGL suffix} {(dat)} .mx
+@deftypefnx {MGL suffix} {(dat)} .my
+@deftypefnx {MGL suffix} {(dat)} .mz
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{float} Maximal (@code{float} &x, @code{float} &y, @code{float} &z) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_max_real (@code{HCDT} dat, @code{float} *x, @code{float} *y, @code{float} *z)
+@end ifclear
+Возвращает минимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
 @end deftypefn
 
+
+@cindex Momentum
+@anchor{.ax} @anchor{.ay} @anchor{.az} @anchor{.aa} @anchor{.sum}
+@anchor{.wx} @anchor{.wy} @anchor{.wz} @anchor{.wa}
+@anchor{.sx} @anchor{.sy} @anchor{.sz} @anchor{.sa}
+@anchor{.kx} @anchor{.ky} @anchor{.kz} @anchor{.ka}
+@deftypefn {MGL suffix} {(dat)} .sum
+@deftypefnx {MGL suffix} {(dat)} .ax
+@deftypefnx {MGL suffix} {(dat)} .ay
+@deftypefnx {MGL suffix} {(dat)} .az
+@deftypefnx {MGL suffix} {(dat)} .aa
+@deftypefnx {MGL suffix} {(dat)} .wx
+@deftypefnx {MGL suffix} {(dat)} .wy
+@deftypefnx {MGL suffix} {(dat)} .wz
+@deftypefnx {MGL suffix} {(dat)} .wa
+@deftypefnx {MGL suffix} {(dat)} .sx
+@deftypefnx {MGL suffix} {(dat)} .sy
+@deftypefnx {MGL suffix} {(dat)} .sz
+@deftypefnx {MGL suffix} {(dat)} .sa
+@deftypefnx {MGL suffix} {(dat)} .kx
+@deftypefnx {MGL suffix} {(dat)} .ky
+@deftypefnx {MGL suffix} {(dat)} .kz
+@deftypefnx {MGL suffix} {(dat)} .ka
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{float} Momentum (@code{char} dir, @code{float} &a, @code{float} &w) @code{const}
+@deftypefnx {Method on @code{mglData}} @code{float} Momentum (@code{char} dir, @code{float} &m, @code{float} &w, @code{float} &s, @code{float} &k) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_momentum_val (@code{HCDT} dat, @code{char} dir, @code{float} *a, @code{float} *w, @code{float} *s, @code{float} *k)
+@end ifclear
+Возвращает нулевой момент (энергию, @math{I=\sum a_i}) и записывает первый (среднее, @math{m = \sum \xi_i a_i/I}), второй (ширину, @math{w^2 = \sum (\xi_i-m)^2 a_i/I}), третий (асимметрия, @math{s = \sum (\xi_i-m)^3 a_i/ I w^3}) и четвёртый моменты (эксцесс, @math{k = \sum (\xi_i-m)^4 a_i / 3 I w^4})). Здесь @math{\xi} -- соответствующая координата если @var{dir} равно @samp{'x'}, @samp{'y'}, @samp{'z'}. В противном случае среднее, ширина, асимметрия, эксцесс равны @math{m = \sum a_i/N}, @math{w^2 = \sum (a_i-m)^2/N} и т.д.
+@end deftypefn
+
+@anchor{.fst}
+@deftypefn {MGL suffix} {(dat)} .fst
+@ifclear UDAV
 @cindex Find
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_first (@code{const HMDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
+@deftypefnx {Method on @code{mglData}} @code{float} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_first (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
+@end ifclear
 Находит положение (после заданного в @var{i}, @var{j}, @var{k}) первого не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
 @end deftypefn
+
+@anchor{.lst}
+@deftypefn {MGL suffix} {(dat)} .lst
+@ifclear UDAV
 @cindex Last
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{float} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_last (@code{const HMDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
+@deftypefnx {Method on @code{mglData}} @code{float} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_last (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
+@end ifclear
 Находит положение (перед заданного в @var{i}, @var{j}, @var{k}) последнего не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_find (@code{const HMDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
+
+@ifclear UDAV
+@deftypefn {Method on @code{mglData}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_find (@code{HCDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
 Возвращает положение первого в направлении @var{dir} не нулевого значения формулы @var{cond}. Поиск начинается с точки @{i,j,k@}.
 @end deftypefn
 @cindex FindAny
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{bool} FindAny (@code{const char *}cond) @code{const}
-@deftypefnx {Функция С} @code{float} mgl_data_find_any (@code{const HMDT} dat, @code{const char *}cond)
+@deftypefn {Method on @code{mglData}} @code{bool} FindAny (@code{const char *}cond) @code{const}
+@deftypefnx {C function} @code{float} mgl_data_find_any (@code{HCDT} dat, @code{const char *}cond)
 Определяет есть ли хоть одно значение массива, удовлетворяющее условию @var{cond}.
 @end deftypefn
+@end ifclear
+
+@anchor{.a}
+@deftypefn {MGL suffix} {(dat)} .a
+Возвращает первое число массива (для @code{.a} это @code{dat->a[0]}).
+@end deftypefn
+
+
 
 @c ------------------------------------------------------------------
-@node Operators, Global functions, Informational functions, Data processing
+@node Operators, Global functions, Data information, Data processing
 @section Операторы
 
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator= (@code{const mglData &}d)
+@deftypefn {MGL command} {} copy @sc{dat} dat2 ['eq'='']
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} operator= (@code{const mglData &}d)
+@end ifclear
 Копирует данные из другого экземпляра.
 @end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator*= (@code{const mglData &}d)
-@deftypefnx {Функция С} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{const HMDT} d)
-Поэлементно умножает массив @var{d}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator/= (@code{const mglData &}d)
-@deftypefnx {Функция С} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{const HMDT} d)
-Поэлементно делит массив @var{d}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator+= (@code{const mglData &}d)
-@deftypefnx {Функция С} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{const HMDT} d)
-Поэлементно прибавляет @var{d}.
-Adds the other data.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator-= (@code{const mglData &}d)
-@deftypefnx {Функция С} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{const HMDT} d)
-Поэлементно вычитает @var{d}.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator*= (@code{float} d)
-@deftypefnx {Функция С} @code{void} mgl_data_mul_num (@code{HMDT} dat, @code{float} d)
-Умножает каждый элемент на число.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator/= (@code{float} d)
-@deftypefnx {Функция С} @code{void} mgl_data_div_num (@code{HMDT} dat, @code{float} d)
-Делит каждый элемент на число.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator+= (@code{float} d)
-@deftypefnx {Функция С} @code{void} mgl_data_add_num (@code{HMDT} dat, @code{float} d)
-Прибавляет число к каждому элементу.
-@end deftypefn
-@deftypefn {Метод класса @code{mglData} (C++, Python)} @code{void} operator-= (@code{float} d)
-@deftypefnx {Функция С} @code{void} mgl_data_sub_num (@code{HMDT} dat, @code{float} d)
-Вычитает число из каждого элемента.
-@end deftypefn
 
-
-@deftypefn {Функция библиотеки} mglData operator+ (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefn {MGL command} {} copy dat @code{val}
+@ifclear UDAV
+@deftypefnx {Method on @code{float}} @code{void} operator= (@code{float} val)
+@end ifclear
+Устанавливает все значения массива равными @var{val}.
+@end deftypefn
+
+@anchor{multo}
+@deftypefn {MGL command} {} multo dat dat2
+@deftypefnx {MGL command} {} multo dat @code{val}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{const mglData &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{HCDT} d)
+@deftypefnx {C function} @code{void} mgl_data_mul_num (@code{HMDT} dat, @code{float} d)
+@end ifclear
+Поэлементно умножает на массив @var{d} или на число @var{val}.
+@end deftypefn
+
+@anchor{divto}
+@deftypefn {MGL command} {} divto dat dat2
+@deftypefnx {MGL command} {} divto dat @code{val}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{const mglData &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{HCDT} d)
+@deftypefnx {C function} @code{void} mgl_data_div_num (@code{HMDT} dat, @code{float} d)
+@end ifclear
+Поэлементно делит на массив @var{d} или на число @var{val}.
+@end deftypefn
+
+@anchor{addto}
+@deftypefn {MGL command} {} addto dat dat2
+@deftypefnx {MGL command} {} addto dat @code{val}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{const mglData &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{HCDT} d)
+@deftypefnx {C function} @code{void} mgl_data_add_num (@code{HMDT} dat, @code{float} d)
+@end ifclear
+Поэлементно прибавляет @var{d} или число @var{val}.
+@end deftypefn
+
+@anchor{subto}
+@deftypefn {MGL command} {} subto dat dat2
+@deftypefnx {MGL command} {} subto dat @code{val}
+@ifclear UDAV
+@deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{const mglData &}d)
+@deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{float} d)
+@deftypefnx {C function} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{HCDT} d)
+@deftypefnx {C function} @code{void} mgl_data_sub_num (@code{HMDT} dat, @code{float} d)
+@end ifclear
+Поэлементно вычитает @var{d} или число @var{val}.
+@end deftypefn
+
+@ifclear UDAV
+@deftypefn {Library Function} mglData operator+ (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator+ (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator+ (@code{const mglData &}a, @code{float} b)
 Возвращает поэлементную сумму данных.
 @end deftypefn
-@deftypefn {Функция библиотеки} mglData operator+ (@code{float} a, @code{const mglData &}b)
-@deftypefnx {Функция библиотеки} mglData operator+ (@code{const mglData &}a, @code{float} b)
-Возвращает поэлементную сумму данных и числа.
-@end deftypefn
 
-@deftypefn {Функция библиотеки} mglData operator- (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefn {Library Function} mglData operator- (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator- (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator- (@code{const mglData &}a, @code{float} b)
 Возвращает поэлементную разность данных.
 @end deftypefn
-@deftypefn {Функция библиотеки} mglData operator- (@code{float} a, @code{const mglData &}b)
-@deftypefnx {Функция библиотеки} mglData operator- (@code{const mglData &}a, @code{float} b)
-Возвращает поэлементную разность числа и данных.
-@end deftypefn
 
-@deftypefn {Функция библиотеки} mglData operator* (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefn {Library Function} mglData operator* (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator* (@code{float} a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator* (@code{const mglData &}a, @code{float} b)
 Возвращает поэлементное произведение данных.
 @end deftypefn
-@deftypefn {Функция библиотеки} mglData operator* (@code{float} a, @code{const mglData &}b)
-@deftypefnx {Функция библиотеки} mglData operator* (@code{const mglData &}a, @code{float} b)
-Возвращает поэлементное произведение данных на число.
-@end deftypefn
 
-@deftypefn {Функция библиотеки} mglData operator/ (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefn {Library Function} mglData operator/ (@code{const mglData &}a, @code{const mglData &}b)
+@deftypefnx {Library Function} mglData operator/ (@code{const mglData &}a, @code{float} b)
 Возвращает поэлементное деление данных.
 @end deftypefn
-@deftypefn {Функция библиотеки} mglData operator/ (@code{const mglData &}a, @code{float} b)
-Возвращает поэлементное деление данных на число.
-@end deftypefn
+@end ifclear
 
 @c ------------------------------------------------------------------
-@node Global functions, , Operators, Data processing
+@node Global functions, Evaluate expression, Operators, Data processing
 @section Глобальные функции
 
+@ifclear UDAV
 Эти функции не методы класса @code{mglData}, но они дают дополнительные возможности по обработке данных. Поэтому я поместил их в эту главу.
-
-@deftypefn {Функция библиотеки} @code{mglData} mglTransform (@code{const mglData &}real, @code{const mglData &}imag, @code{const char *}type)
-@deftypefnx {Функция С} @code{HMDT} mgl_transform (@code{const HMDT} real, @code{const HMDT} imag, @code{const char *}type)
+@end ifclear
+
+@anchor{transform}
+@deftypefn {MGL command} {} transform @sc{dat} 'type' real imag
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglTransform (@code{const mglData &}real, @code{const mglData &}imag, @code{const char *}type)
+@deftypefnx {C function} @code{HMDT} mgl_transform (@code{HCDT} real, @code{HCDT} imag, @code{const char *}type)
+@end ifclear
 Выполняет интегральное преобразование комплексных данных @var{real}, @var{imag} в выбранном направлении и возвращает модуль результата. Порядок и тип преобразований задается строкой @var{type}: первый символ для x-направления, второй для y-направления, третий для z-направления. Возможные символы: @samp{f} -- прямое преобразование Фурье, @samp{i} -- обратное преобразование Фурье, @samp{s} -- синус преобразование, @samp{c} -- косинус преобразование, @samp{h} -- преобразование Ханкеля, @samp{n} или @samp{ } -- нет преобразования.
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglTransformA @code{const mglData &}ampl, @code{const mglData &}phase, @code{const char *}type)
-@deftypefnx {Функция С} @code{HMDT} mgl_transform_a @code{const HMDT} ampl, @code{const HMDT} phase, @code{const char *}type)
+@anchor{transforma}
+@deftypefn {MGL command} {} transforma @sc{dat} 'type' ampl phase
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglTransformA @code{const mglData &}ampl, @code{const mglData &}phase, @code{const char *}type)
+@deftypefnx {C function} @code{HMDT} mgl_transform_a @code{HCDT} ampl, @code{HCDT} phase, @code{const char *}type)
+@end ifclear
 Аналогично предыдущему с заданными амплитудой @var{ampl} и фазой @var{phase} комплексных чисел.
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglSTFA (@code{const mglData &}real, @code{const mglData &}imag, @code{int} dn, @code{char} dir=@code{'x'})
-@deftypefnx {Функция С} @code{HMDT} mgl_data_stfa (@code{const HMDT} real, @code{const HMDT} imag, @code{int} dn,@code{char} dir)
+@anchor{fourier}
+@deftypefn {MGL command} {} fourier reDat imDat 'dir'
+@ifclear UDAV
+@deftypefnx {Global function} @code{void} mglFourier @code{const mglData &}re, @code{const mglData &}im, @code{const char *}dir)
+@deftypefnx {C function} @code{void} mgl_data_fourier @code{HCDT} re, @code{HCDT} im, @code{const char *}dir)
+@end ifclear
+Выполняет Фурье преобразование для комплексных данных @var{re}+i*@var{im} в направлениях @var{dir}. Результат помещается обратно в массивы @var{re} и @var{im}.
+@end deftypefn
+
+@anchor{stfad}
+@deftypefn {MGL command} {} stfad @sc{res} real imag @code{dn} ['dir'='x']
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglSTFA (@code{const mglData &}real, @code{const mglData &}imag, @code{int} dn, @code{char} dir=@code{'x'})
+@deftypefnx {C function} @code{HMDT} mgl_data_stfa (@code{HCDT} real, @code{HCDT} imag, @code{int} dn,@code{char} dir)
+@end ifclear
 Выполняет оконное преобразование Фурье длиной @var{dn} для комплексных данных @var{real}, @var{imag} и возвращает модуль результата. Например, для @var{dir}=@samp{x} результат будет иметь размер @{int(nx/dn), dn, ny@} и будет равен @math{res[i,j,k]=|\sum_d^dn exp(I*j*d)*(real[i*dn+d,k]+I*imag[i*dn+d,k])|/dn}.
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglPDE (@code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{mglPoint} Min, @code{mglPoint} Max, @code{float} dz=@code{0.1}, @code{float} k0=@code{100})
-@deftypefnx {Функция С} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{const HMDT} ini_re, @code{const HMDT} ini_im, @code{float} dz, @code{float} k0)
+@anchor{pde}
+@deftypefn {MGL command} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{float} dz=@code{0.1}, @code{float} k0=@code{100}, @code{const char *}opt=@code{""})
+@deftypefnx {C function} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{float} dz, @code{float} k0, @code{const char *}opt)
+@end ifclear
 Решает уравнение в частных производных du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Координаты в уравнении и в решении полагаются в диапазоне осей координат. Замечу, что внутри этот диапазон увеличивается в 3/2 раза для уменьшения отражения от границ расчетного интервала. Параметр @var{dz} задает шаг по эволюционной координате z. В данный момент использован упрощенный алгоритм, когда все ``смешанные'' члена (типа @samp{x*p}->x*d/dx) исключаются. Например, в 2D случае это функции типа @math{ham = f(p,z) + g(x,z,u)}. При этом допускаются коммутирующие комбинации (типа @samp{x*q}->x*d/dy). Переменная @samp{u} используется для обозначения амплитуды поля |u|. Это позволяет решать нелинейные задачи -- например, нелинейное уравнение Шредингера @code{ham='p^2+q^2-u^2'}. Также можно указать мнимую часть для поглощения (типа @code{ham = 'p^2+i*x*(x>0)'}), но только если зависимость от @samp{i} линейная, т.е. @math{ham = hre+i*him}. @sref{PDE sample}
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglRay (@code{const char *}ham, @code{mglPoint} r0, @code{mglPoint} p0, @code{float} dt=@code{0.1}, @code{float} tmax=@code{10})
-@deftypefnx {Функция С} @code{HMDT} mgl_ray_trace (@code{const char *}ham, @code{float} x0, @code{float} y0, @code{float} z0, @code{float} px, @code{float} py, @code{float} pz, @code{float} dt, @code{float} tmax)
+@anchor{ray}
+@deftypefn {MGL command} {} ray @sc{res} 'ham' @code{x0 y0 z0 p0 q0 v0 [dt=0.1 tmax=10]}
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglRay (@code{const char *}ham, @code{mglPoint} r0, @code{mglPoint} p0, @code{float} dt=@code{0.1}, @code{float} tmax=@code{10})
+@deftypefnx {C function} @code{HMDT} mgl_ray_trace (@code{const char *}ham, @code{float} x0, @code{float} y0, @code{float} z0, @code{float} px, @code{float} py, @code{float} pz, @code{float} dt, @code{float} tmax)
+@end ifclear
 Решает систему геометрооптических уравнений d@emph{r}/dt = d @var{ham}/d@emph{p}, d@emph{p}/dt = -d @var{ham}/d@emph{r}. Это гамильтоновы уравнения для траектории частицы в 3D случае. Гамильтониан @var{ham} может зависеть от координат @samp{x}, @samp{y}, @samp{z}, импульсов @samp{p}=px, @samp{q}=py, @samp{v}=pz и времени @samp{t}: @math{ham = H(x,y,z,p,q,v,t)}. Начальная точка (при @code{t=0}) задается переменными @{@var{x0}, @var{y0}, @var{z0}, @var{p0}, @var{q0}, @var{v0}@}. Параметры @var{dt} и @var{tmax} задают шаг и максимальное время интегрирования. Результат -- массив @{x,y,z,p,q,v,t@} с размером @{7 * int(@var{tmax}/@var{dt}+1) @}. @sref{Beam tracing sample}
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{const mglData &}ray, @code{float} r=@code{1}, @code{float} k0=@code{100}, @code{mglData *}xx=@code{0}, @code{mglData *}yy=@code{0}, @code{bool} UseR=@code{true})
-@deftypefnx {Функция С} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{const HMDT} ini_re, @code{const HMDT} ini_im, @code{const HMDT} ray, @code{float} r, @code{float} k0, @code{HMDT} xx, @code{HMDT} yy)
+@anchor{qo2d}
+@deftypefn {MGL command} {} qo2d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{const mglData &}ray, @code{float} r=@code{1}, @code{float} k0=@code{100}, @code{mglData *}xx=@code{0}, @code{mglData *}yy=@code{0})
+@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglData &}ini_re, @code{const mglData &}ini_im, @code{const mglData &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{float} r=@code{1}, @code{float} k0=@code{100})
+@deftypefnx {C function} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{float} r, @code{float} k0, @code{HMDT} xx, @code{HMDT} yy)
+@end ifclear
 Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @code{mglRay()}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx} и @var{yy} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @code{mglPDE()}. @sref{Beam tracing sample}
 @end deftypefn
 
-@deftypefn {Функция библиотеки} @code{mglData} mglJacobian (@code{const mglData &}x, @code{const mglData &}y)
-@deftypefnx {Функция библиотеки} @code{mglData} mglJacobian (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z)
-@deftypefnx {Функция С} @code{HMDT} mgl_jacobian_2d (@code{const HMDT} x, @code{const HMDT} y)
-@deftypefnx {Функция С} @code{HMDT} mgl_jacobian_3d (@code{const HMDT} x, @code{const HMDT} y, @code{const HMDT} z)
+@anchor{jacobian}
+@deftypefn {MGL command} {} jacobian @sc{res} xdat ydat [zdat]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglJacobian (@code{const mglData &}x, @code{const mglData &}y)
+@deftypefnx {Global function} @code{mglData} mglJacobian (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z)
+@deftypefnx {C function} @code{HMDT} mgl_jacobian_2d (@code{HCDT} x, @code{HCDT} y)
+@deftypefnx {C function} @code{HMDT} mgl_jacobian_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
+@end ifclear
 Вычисляет якобиан преобразования @{i,j,k@} в @{@var{x},@var{y},@var{z}@}, где координаты @{i,j,k@} полагаются нормированными в интервал [0,1]. Якобиан находится по формуле det||@math{dr_\alpha/d\xi_\beta}||, где @math{r}=@{@var{x},@var{y},@var{z}@} и @math{\xi}=@{i,j,k@}. Все размерности всех массивов должны быть одинаковы. Данные должны быть трехмерными если указаны все 3 массива @{@var{x},@var{y},@var{z}@} или двумерными если только 2 массива @{@var{x},@var{y}@}.
 @end deftypefn
 
+@anchor{triangulation}
+@deftypefn {MGL command} {} triangulation @sc{res} xdat ydat [zdat]
+@ifclear UDAV
+@deftypefnx {Global function} @code{mglData} mglTriangulation (@code{const mglData &}x, @code{const mglData &}y)
+@deftypefnx {Global function} @code{mglData} mglTriangulation (@code{const mglData &}x, @code{const mglData &}y, @code{const mglData &}z)
+@deftypefnx {C function} @code{HMDT} mgl_triangulation_2d (@code{HCDT} x, @code{HCDT} y)
+@deftypefnx {C function} @code{HMDT} mgl_triangulation_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
+@end ifclear
+Выполняет триангуляцию для произвольно расположенных точек с координатами @{@var{x},@var{y},@var{z}@} (т.е. находит треугольники, соединяющие точки). Первая размерность всех массивов должна быть одинакова @code{x.nx=y.nx=z.nx}. Получившийся массив можно использовать в @ref{triplot} или @ref{tricont} для визуализации реконструированной поверхности.
+@end deftypefn
+
+
+@c ------------------------------------------------------------------
+@node Evaluate expression, , Global functions, Data processing
+@section Вычисление выражений
+
+@ifset UDAV
+В MGL скриптах в качестве аргументов команд можно использовать произвольные формулы от существующих массивов данных и констант. Есть только 2 ограничения: формула не должна содержать пробелов (чтобы распознаваться как один аргумент), формула не может быть аргументом, который может быть пересоздан при выполнении скрипта.
+@end ifset
+
+@ifclear UDAV
+В MathGL есть специальный класс @code{mglExpr} для вычисления формул заданных строкой. Класс определён в @code{#include <mgl/mgl.h>}. При создании класса происходит разбор формулы в древовидную структуру. А при вычислении только выполняется достаточно быстрый обход по дереву. В данный момент нет различия между верхним и нижним регистром. Если аргумент какой-либо функции лежит вне её области определения, то возвращается NaN. @xref{Textual formulas}.
+
+@deftypefn {Constructor on @code{mglExpr}} @code{} mglExpr (@code{const char *}expr)
+@deftypefnx {C function} @code{HMEX} mgl_create_expr (@code{const char *}expr)
+Разбирает формулу @var{expr} и создает древовидную структуру, содержащую последовательность вызова функций и операторов для последующего быстрого вычисления формулы с помощью функций @code{Calc()} и/или @code{CalcD()}.
+@end deftypefn
+
+@deftypefn {Destructor on @code{mglExpr}} @code{} ~mglExpr ()
+@deftypefnx {C function} @code{HMEX} mgl_delete_expr (@code{HMEX} ex)
+Удаляет объект типа @code{mglExpr}.
+@end deftypefn
+
+@deftypefn {Method on @code{mglExpr}} @code{float} Eval (@code{float} x, @code{float} y, @code{float} z)
+@deftypefnx {C function} @code{float} mgl_expr_eval (@code{HMEX} ex, @code{float} x, @code{float} y, @code{float} z)
+Вычисляет значение формулы для @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
+@end deftypefn
+
+@deftypefn {Method on @code{mglExpr}} @code{float} Eval (@code{float} var[26])
+@deftypefnx {C function} @code{float} mgl_expr_eval_v (@code{HMEX} ex, @code{float *}var)
+Вычисляет значение формулы для переменных в массиве @var{var}[0,...,'z'-'a'].
+@end deftypefn
+
+
+@deftypefn {Method on @code{mglExpr}} @code{float} Diff (@code{char} dir, @code{float} x, @code{float} y, @code{float} z)
+@deftypefnx {C function} @code{float} mgl_expr_diff (@code{HMEX} ex, @code{char} dir, @code{float} x, @code{float} y, @code{float} z)
+Вычисляет производную от формулы по переменной @var{dir} для @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
+@end deftypefn
+
+@deftypefn {Method on @code{mglExpr}} @code{float} Diff (@code{char} dir, @code{float} var[26])
+@deftypefnx {C function} @code{float} mgl_expr_diff_v (@code{HMEX} ex, @code{char} dir, @code{float *}var)
+Вычисляет производную от формулы по переменной @var{dir} для переменных в массиве @var{var}[0,...,'z'-'a'].
+@end deftypefn
+
+@end ifclear
index ec8029fa2ddff85afb1e6f6537aa023cc65443e5..a3b9a411ca299a90d4c2a62bfad4865e63ba80bc 100644 (file)
@@ -81,7 +81,7 @@ Positive aspects are: batch processing of similar data set (for example, a set o
 @item
 @emph{Drawing in memory with the following displaying by other graphical program.}
 
-In this case the programmer has more freedom in selecting the window libraries (not only FLTK, Qt or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``settled'' programs.
+In this case the programmer has more freedom in selecting the window libraries (not only FLTK, Qt or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``stand alone'' programs.
 
 @item
 @emph{Using FLTK or Qt widgets provided by MathGL}
@@ -126,7 +126,7 @@ int main(int argc,char **argv)
   return gr.Run();
 }
 @end verbatim
-Here function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program. For compilation, just execute the command
+Here callback function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program. For compilation, just execute the command
 @verbatim
 gcc test.cpp -lmgl-wnd -lmgl
 @end verbatim
@@ -157,7 +157,7 @@ int main(int argc,char **argv)
 Or use pure C-functions:
 @verbatim
 #include <mgl/mgl_cf.h>
-int sample(HMGL gr)
+int sample(HMGL gr, void *)
 {
   mgl_rotate(gr,60,40,0);
   mgl_box(gr);
@@ -212,7 +212,7 @@ This can be important if you create a console program in computer/cluster where
 
 The only difference from the previous variant (using windows) is manual switching on the transparency  @code{Alpha} and lightning @code{Light}, if you need it. The usage of frames (see @ref{Animation}) is not advisable since the whole image is prepared each time. If function @code{sample} contains frames then only last one will be saved to the file. In principle, one does not need to separate drawing functions in case of direct file writing in consequence of the single calling of this function for each picture. However, one may use the same drawing procedure to create a plot with changeable parameters, to export in different file types, to emphasize the drawing code and so on. So, in future I will put the drawing in the separate function.
 
-The code for export in vector EPS file looks the same:
+The code for export into other formats (for example, into vector EPS file) looks the same:
 @verbatim
 #include <mgl/mgl.h>
 int main(int ,char **)
@@ -245,7 +245,7 @@ int sample(mglGraph *gr)
   return gr->GetNumFrame();   // returns the frame number
 }
 @end verbatim
-First, the function creates a frame @code{NewFrame()} for rotated axes and draws the bounding box. After the frame drawing the function @code{EndFrame()} @strong{must be} called! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
+First, the function creates a frame by calling @code{NewFrame()} for rotated axes and draws the bounding box.  The function @code{EndFrame()} @strong{must be} called after the frame drawing! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
 
 Note, that such kind of animation is rather slow and not well suitable for visualization of running calculations. For the last case one can use @code{Update()} function. The most simple case for doing this is to use @code{mglDraw} class and reimplement its @code{Calc()} method.
 @verbatim
@@ -263,9 +263,9 @@ void Foo::Calc()
 {
   for(int i=0;i<30;i++)   // do calculation
   {
-    sleep(2);           // which can be very long
+    sleep(2);             // which can be very long
     pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
-    Gr->Update();        // update window
+    Gr->Update();         // update window
   }
 }
 //-----------------------------------------------------
@@ -307,6 +307,7 @@ int main(int argc,char **argv)
 
 Pictures with @strong{animation can be saved in file(s)} as well. You can: export in animated GIF, or save each frame in separate file (usually JPEG) and convert these files into the movie (for example, by help of ImageMagic). Let me show both methods.
 
+@anchor{GIF}
 The simplest methods is making animated GIF. There are 3 steps: (1) open GIF file by @code{StartGIF()} function; (2) create the frames by calling @code{NewFrame()} before and @code{EndFrame()} after plotting; (3) close GIF by @code{CloseGIF()} function. So the simplest code for ``running'' sinusoid will look like this:
 @verbatim
 #include <mgl/mgl.h>
@@ -330,6 +331,7 @@ int main(int ,char **)
 }
 @end verbatim
 
+@anchor{MPEG}
 The second way is saving each frame in separate file (usually JPEG) and later make the movie from them. MathGL have special function for saving frames -- it is @code{WriteFrame()}. This function save each frame with automatic name @samp{frame0001.jpg, frame0002.jpg} and so on. Here prefix @samp{frame} is defined by @var{PlotId} variable of @code{mglGraph} class. So the similar code will look like this:
 @verbatim
 #include <mgl/mgl.h>
index b25bd38492b750e2c722c5fcb46b1ec130458ebb..ec8029fa2ddff85afb1e6f6537aa023cc65443e5 100644 (file)
@@ -1,16 +1,65 @@
 @c ------------------------------------------------------------------
 @chapter MathGL examples
 
-This chapter contain information about basic and advanced MathGL, hints and samples for all types of graphics. I recommend you read first 2 sections one after another and at least look on ``Hints'' section. Also I recommend you to look at @ref{General concepts} and @ref{FAQ}. Sample code for some of these examples can be found in @uref{http://mathgl.sf.net/pictures.html} and in @ref{Samples}.
+This chapter contain information about basic and advanced MathGL, hints and samples for all types of graphics. I recommend you read first 2 sections one after another and at least look on @ref{Hints} section. Also I recommend you to look at @ref{General concepts} and @ref{FAQ}.
+
+Note, that MathGL v.2.* have only 2 end-user interfaces: one for C/Fortran and similar languages which don't support classes, another one for C++/Python/Octave and similar languages which support classes. So, most of samples placed in this chapter can be run as is (after minor changes due to different syntaxes for different languages). For example, the C++ code
+@verbatim
+#include <mgl/mgl.h>
+int main()
+{
+  mglGraph gr;
+  gr.FPlot("sin(pi*x)");
+  gr.WriteFrame("test.png");
+}
+@end verbatim
+in Python will be as
+@verbatim
+from mathgl import *
+gr = mglGraph();
+gr.FPlot("sin(pi*x)");
+gr.WriteFrame("test.png");
+@end verbatim
+in Octave will be as (you need first install MathGL package by command @code{octave:1> pkg install /usr/share/mathgl/octave/mathgl.tar.gz} from @code{sudo octave})
+@verbatim
+gr = mglGraph();
+gr.FPlot("sin(pi*x)");
+gr.WriteFrame("test.png");
+@end verbatim
+in C will be as
+@verbatim
+#include <mgl/mgl_cf.h>
+int main()
+{
+  HMGL gr = mgl_create_graph(600,400);
+  mgl_fplot(gr,"sin(pi*x)","","");
+  mgl_write_frame(gr,"test.png","");
+  mgl_delete_graph(gr);
+}
+@end verbatim
+in Fortran will be as
+@verbatim
+integer gr, mgl_create_graph
+gr = mgl_create_graph(600,400);
+call mgl_fplot(gr,'sin(pi*x)','','');
+call mgl_write_frame(gr,'test.png','');
+call mgl_delete_graph(gr);
+@end verbatim
+and so on.
+
+
 
 @menu
-* Basic usage::                 
-* Advanced usage::              
-* Data handling::               
-* Data plotting::               
-* C/Fortran interface::         
-* MathGL and PyQt::
+* Basic usage::
+* Advanced usage::
+* Data handling::
+* Data plotting::
+* 1D samples::
+* 2D samples::
+* 3D samples::
+* Vector field samples::
 * Hints::
+* FAQ::
 @end menu
 
 @c ------------------------------------------------------------------
@@ -20,236 +69,456 @@ This chapter contain information about basic and advanced MathGL, hints and samp
 MathGL library can be used by several manners. Each has positive and negative sides:
 @itemize @bullet
 @item
-@emph{The using of MathGL library features for creating graphical window (requires FLTK or GLUT libraries).}
+@emph{Using of MathGL library features for creating graphical window (requires FLTK, Qt or GLUT libraries).}
 
 Positive side is the possibility to view the plot at once and to modify it (rotate, zoom or switch on transparency or lighting) by hand or by mouse. Negative sides are: the need  of X-terminal and limitation consisting in working with the only one set of data at a time.
+
 @item
 @emph{Direct writing to file in bitmap or vector format without creation of graphical window.}
 
 Positive aspects are: batch processing of similar data set (for example, a set of resulting data files for different calculation parameters), running from the console program (including the cluster calculation), fast and automated drawing, saving pictures for further analysis (or demonstration). Negative sides are: the usage of the external program for picture viewing. Also, the data plotting is non-visual. So, you have to imagine the picture (view angles, lighting and so on) before the plotting. I recommend to use graphical window for determining the optimal parameters of plotting on the base of some typical data set. And later use these parameters for batch processing in console program.
+
 @item
 @emph{Drawing in memory with the following displaying by other graphical program.}
 
-In this case the programmer has more freedom in selecting the window libraries (not only FLTK or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``settled'' programs.
+In this case the programmer has more freedom in selecting the window libraries (not only FLTK, Qt or GLUT), in positioning and surroundings control and so on. I recommend to use such way for ``settled'' programs.
+
+@item
+@emph{Using FLTK or Qt widgets provided by MathGL}
+
+Here one can use a set of standard widgets which support export to many file formats, copying to clipboard, handle mouse and so on. 
 @end itemize
 
+MathGL drawing can be created not only by object oriented languages (like, C++ or Python), but also by pure C or Fortran-like languages. The usage of last one is mostly identical to usage of classes (except the different function names). But there are some differences. C functions must have argument HMGL (for graphics) and/or HMDT (for data arrays) which specifies the object for drawing or manipulating (changing). Fortran users may regard these variables as integer. So, firstly the user has to create this object by function mgl_create_*() and has to delete it after the using by function mgl_delete_*().
+@c Also, all arguments of C function have to be defined. So there are several functions with practically identical names doing practically the same. But some of them have simplified interface for the quick plotting and some of them have access to all plotting parameters for manual tunning.
+
 Let me consider the aforesaid in more detail.
 
 @menu
-* Using FLTK/GLUT window::      
-* Drawing to file::             
-* Drawing in memory::           
-* Using QMathGL::               
+* Using MathGL window::
+* Drawing to file::
+* Animation::
+* Drawing in memory::
+* Using QMathGL::
+* MathGL and PyQt::
 @end menu
 
 
 @c ------------------------------------------------------------------
-@node Using FLTK/GLUT window, Drawing to file, , Basic usage
-@subsection Using FLTK/Qt/GLUT window
+@node Using MathGL window, Drawing to file, , Basic usage
+@subsection Using MathGL window
 @cindex window
 @cindex widgets
 
-The ``interactive'' way of drawing in MathGL consists in window creation  with help of class @code{mglGraphFLTK}, @code{mglGraphQT} or @code{mglGraphGLUT} (@pxref{Widget classes}) and the following drawing in this window. There is a corresponding code:
+The ``interactive'' way of drawing in MathGL consists in window creation  with help of class @code{mglWindow} or @code{mglGLUT} (see @ref{Widget classes}) and the following drawing in this window. There is a corresponding code:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->Rotate(60,40);
-        gr->Box();
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mglGraphFLTK gr;
-        gr.Window(argc,argv,sample,"MathGL examples");
-        return mglFlRun();
-    }
+#include <mgl/window.h>
+int sample(mglGraph *gr)
+{
+  gr->Rotate(60,40);
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  mglWindow gr(sample,"MathGL examples");
+  return gr.Run();
+}
+@end verbatim
+Here function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program. For compilation, just execute the command
+@verbatim
+gcc test.cpp -lmgl-wnd -lmgl
 @end verbatim
-Here function @code{sample} is defined. This function does all drawing. Other function @code{main} is entry point function for console program. Arguments of @code{main} should be transfered to @code{Window()} since it may contain OS specific information (@pxref{mglGraphAB class}).
 
 Alternatively you can create yours own class inherited from class @code{mglDraw} and re-implement the function @code{Draw()} in it:
 @verbatim
-    class Foo : public mglDraw
-    {
-    public:
-        int Draw(mglGraph *gr);
-    } foo;
-    //-----------------------------------------------------
-    int Foo::Draw(mglGraph *gr)
-    {
-        gr->Rotate(60,40);
-        gr->Box();
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mglGraphFLTK gr;
-        gr.Window(argc,argv,&foo,"MathGL examples");
-        return mglFlRun();
-    }
-@end verbatim
+#include <mgl/window.h>
+class Foo : public mglDraw
+{
+public:
+  int Draw(mglGraph *gr);
+};
+//-----------------------------------------------------
+int Foo::Draw(mglGraph *gr)
+{
+  gr->Rotate(60,40);
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  Foo foo;
+  mglWindow gr(&foo,"MathGL examples");
+  return gr.Run();
+}
+@end verbatim
+Or use pure C-functions:
+@verbatim
+#include <mgl/mgl_cf.h>
+int sample(HMGL gr)
+{
+  mgl_rotate(gr,60,40,0);
+  mgl_box(gr);
+}
+int main(int argc,char **argv)
+{
+  HMGL gr;
+  gr = mgl_create_graph_qt(sample,"MathGL examples",0);
+  return mgl_qt_run();
+/* generally I should call mgl_delete_graph() here,
+ * but I omit it in main() function. */
+}
+@end verbatim
+
+The similar code can be written for @code{mglGLUT} window (function @code{sample()} is the same):
+@verbatim
+#include <mgl/glut.h>
+int main(int argc,char **argv)
+{
+  mglGLUT gr(sample,"MathGL examples");
+  return 0;
+}
+@end verbatim
+
+The rotation, shift, zooming, switching on/off transparency and lighting can be done with help of tool-buttons (for @code{mglWindow}) or by hot-keys: @samp{a}, @samp{d}, @samp{w}, @samp{s} for plot rotation, @samp{r} and @samp{f} switching on/off transparency and lighting. Press @samp{x} for exit (or closing the window).
+
+In this example function @code{sample} rotates axes (@code{Rotate()}, @pxref{Subplots and rotation}) and draws the bounding box (@code{Box()}). Drawing is placed in separate function since it will be used on demand when window canvas needs to be redrawn.
+
+@c ------------------------------------------------------------------
+@node Drawing to file, Animation, Using MathGL window, Basic usage
+@subsection Drawing to file
+
+Another way of using MathGL library is the direct writing of the picture to the file. It is most usable for plot creation during long calculation or for using of small programs (like Matlab or Scilab scripts) for visualizing repetitive sets of data. But the speed of drawing is much higher in comparison with a script language.
 
-The similar code can be written for @code{mglGraphQT} or for @code{mglGraphGLUT} window (function @code{sample()} is the same):
+The following code produces a bitmap PNG picture:
 @verbatim
-    int main(int argc,char **argv)
-    {
-        mglGraphGLUT gr;
-        gr.Window(argc,argv,sample,"MathGL examples");
-        return 0;
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  gr.Alpha(true);   gr.Light(true);
+  sample(&gr);              // The same drawing function.
+  gr.WritePNG("test.png");  // Don't forget to save the result!
+  return 0;
+}
+@end verbatim
+ For compilation, you need only libmgl library not the one with widgets
+@verbatim
+gcc test.cpp -lmgl
 @end verbatim
+This can be important if you create a console program in computer/cluster where X-server (and widgets) is inaccessible.
 
-The rotation, shift, zooming, switching on/off transparency and lighting can be done with help of tool-buttons (for @code{mglGraphFLTK} and @code{mglGraphQT}) or by hot-keys: @samp{a}, @samp{d}, @samp{w}, @samp{s} for plot rotation, @samp{r} and @samp{f} switching on/off transparency and lighting. Press @samp{x} for exit (or closing the window).
+The only difference from the previous variant (using windows) is manual switching on the transparency  @code{Alpha} and lightning @code{Light}, if you need it. The usage of frames (see @ref{Animation}) is not advisable since the whole image is prepared each time. If function @code{sample} contains frames then only last one will be saved to the file. In principle, one does not need to separate drawing functions in case of direct file writing in consequence of the single calling of this function for each picture. However, one may use the same drawing procedure to create a plot with changeable parameters, to export in different file types, to emphasize the drawing code and so on. So, in future I will put the drawing in the separate function.
 
-In this example function @code{sample} rotates axes (@code{Rotate()}, @pxref{Transformation matrix}) and draws the bounding box (@code{Box()}). Drawing procedure is separated in a function since it will be used on demand when window canvas needs to be redrawn. Widget classes (@code{mglGraphFLTK}, @code{mglGraphGLUT} and so on) support a delayed drawing, when all plotting functions are called once at the beginning of writing to memory lists. Further program displays the saved lists faster. Resulting redrawing will be faster but it requires sufficient memory. Several lists (frames) can be displayed one after another (by pressing @samp{,}, @samp{.}) or run as cinema. To switch these feature on one needs to modify function @code{sample}:
+The code for export in vector EPS file looks the same:
 @verbatim
-    int sample1(mglGraph *gr, void *)
-    {
-        gr->NewFrame();             // the first frame
-        gr->Rotate(60,40);
-        gr->Box();
-        gr->EndFrame();             // end of the first frame
-        gr->NewFrame();             // the second frame
-        gr->Box();
-        gr->Axis("xy");
-        gr->EndFrame();             // end of the second frame
-        return GetNumFrame();       // returns the frame number
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  gr.Light(true);
+  sample(&gr);              // The same drawing function.
+  gr.WriteEPS("test.eps");  // Don't forget to save the result!
+  return 0;
+}
 @end verbatim
-First, the function creates a frame @code{NewFrame()} for rotated axes and draws the bounding box. After the frame drawing the function @code{EndFrame()} @strong{must be} called! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
+The difference from the previous one is using other function @code{WriteEPS()} for EPS format instead of function @code{WritePNG()}. Also, there is no switching on of the plot transparency @code{Alpha} since EPS format does not support it.
 
 @c ------------------------------------------------------------------
-@node Drawing to file, Drawing in memory, Using FLTK/GLUT window, Basic usage
-@subsection Drawing to file
+@node Animation, Drawing in memory, Drawing to file, Basic usage
+@subsection Animation
 
-Another way of using MathGL library is the direct picture writing to file. It is most usable for plot creating during calculation or for using of small programs (like Matlab or Scilab scripts) for visualizing repetitive sets of data. But the speed of drawing is much higher in comparison with a script language. There are two classes for exporting in file: class @code{mglGraphZB} saves in bitmap format (like PNG), @code{mglGraphPS} saves in vector PostScript format (@pxref{Plotter classes}).
+Widget classes (@code{mglWindow}, @code{mglGLUT}) support a delayed drawing, when all plotting functions are called once at the beginning of writing to memory lists. Further program displays the saved lists faster. Resulting redrawing will be faster but it requires sufficient memory. Several lists (frames) can be displayed one after another (by pressing @samp{,}, @samp{.}) or run as cinema. To switch these feature on one needs to modify function @code{sample}:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->NewFrame();             // the first frame
+  gr->Rotate(60,40);
+  gr->Box();
+  gr->EndFrame();             // end of the first frame
+  gr->NewFrame();             // the second frame
+  gr->Box();
+  gr->Axis("xy");
+  gr->EndFrame();             // end of the second frame
+  return gr->GetNumFrame();   // returns the frame number
+}
+@end verbatim
+First, the function creates a frame @code{NewFrame()} for rotated axes and draws the bounding box. After the frame drawing the function @code{EndFrame()} @strong{must be} called! The second frame contains the bounding box and axes @code{Axis("xy")} in the initial (unrotated) coordinates. Function @code{sample} returns the number of created frames @code{GetNumFrame()}.
 
-The following code produces a bitmap PNG picture:
+Note, that such kind of animation is rather slow and not well suitable for visualization of running calculations. For the last case one can use @code{Update()} function. The most simple case for doing this is to use @code{mglDraw} class and reimplement its @code{Calc()} method.
+@verbatim
+#include <mgl/window.h>
+class Foo : public mglDraw
+{
+  mglPoint pnt;  // some result of calculation
+public:
+  mglWindow *Gr;  // graphics to be updated
+  int Draw(mglGraph *gr);
+  void Calc();
+} foo;
+//-----------------------------------------------------
+void Foo::Calc()
+{
+  for(int i=0;i<30;i++)   // do calculation
+  {
+    sleep(2);           // which can be very long
+    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
+    Gr->Update();        // update window
+  }
+}
+//-----------------------------------------------------
+int Foo::Draw(mglGraph *gr)
+{
+  gr->Line(mglPoint(),pnt,"Ar2");
+  gr->Box();
+  return 0;
+}
+//-----------------------------------------------------
+int main(int argc,char **argv)
+{
+  mglWindow gr(&foo,"MathGL examples");
+  foo.Gr = &gr;   foo.Run();
+  return gr.Run();
+}
+@end verbatim
+
+Previous sample can be run in C++ only since it use C++ class mglDraw. However similar idea can be used even in Fortran or SWIG-based (Python/Octave/...) if one use FLTK window. Such limitation come from the Qt requirement to be run in the primary thread only. The sample code will be:
+@verbatim
+int main(int argc,char **argv)
+{
+  mglWindow gr("test");   // create window
+  gr.RunThr();            // run event loop in separate thread
+  for(int i=0;i<10;i++)   // do calculation
+  {
+    sleep(1);             // which can be very long
+    pnt = mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1);
+    gr.Clf();             // make new drawing
+    gr.Line(mglPoint(),pnt,"Ar2");
+    char str[10] = "i=0"; str[3] = '0'+i;
+    gr.Puts(mglPoint(),"");
+    gr.Update();          // update window when you need it
+  }
+  return 0;   // finish calculations and close the window
+}
+@end verbatim
+
+
+Pictures with @strong{animation can be saved in file(s)} as well. You can: export in animated GIF, or save each frame in separate file (usually JPEG) and convert these files into the movie (for example, by help of ImageMagic). Let me show both methods.
+
+The simplest methods is making animated GIF. There are 3 steps: (1) open GIF file by @code{StartGIF()} function; (2) create the frames by calling @code{NewFrame()} before and @code{EndFrame()} after plotting; (3) close GIF by @code{CloseGIF()} function. So the simplest code for ``running'' sinusoid will look like this:
 @verbatim
-    int main(int ,char **)
-    {
-        mglGraphZB gr;
-        gr.Alpha(true);
-        gr.Light(true);             gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);           // The same drawing function.
-        gr.WritePNG("test.png");    // Don't forget to save the result!
-        return 0;
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  mglData dat(100);
+  char str[32];
+  gr.StartGIF("sample.gif");
+  for(int i=0;i<40;i++)
+  {
+    gr.NewFrame();     // start frame
+    gr.Box();          // some plotting
+    for(int j=0;j<dat.nx;j++)
+      dat.a[j]=sin(M_PI*j/dat.nx+M_PI*0.05*i);
+    gr.Plot(dat,"b");
+    gr.EndFrame();     // end frame
+  }
+  gr.CloseGIF();
+  return 0;
+}
 @end verbatim
-The only difference from the previous (using windows) variant is manual switching the transparency  @code{Alpha} and lightning @code{Light} on, if the plot requires it. The using of frames is not advisable since the whole image is prepared each time. If function @code{sample} contains frames then each frame will be saved to a separate file. In principle, one does not need to separate drawing functions in case of direct file writing in consequence of the single calling of this function for each picture. However, one may use the same drawing procedure to create a plot with changed parameters, to export in different file types, to emphasize the drawing code and so on. So, in future I will put the drawing in separate function.
 
-The code for export in vector EPS file looks the same:
+The second way is saving each frame in separate file (usually JPEG) and later make the movie from them. MathGL have special function for saving frames -- it is @code{WriteFrame()}. This function save each frame with automatic name @samp{frame0001.jpg, frame0002.jpg} and so on. Here prefix @samp{frame} is defined by @var{PlotId} variable of @code{mglGraph} class. So the similar code will look like this:
 @verbatim
-    int main(int ,char **)
-    {
-        mglGraphPS gr;
-        gr.Light(true);             gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);           // The same drawing function.
-        gr.WriteEPS("test.eps");    // Don't forget to save the result!
-        return 0;
-    }
+#include <mgl/mgl.h>
+int main(int ,char **)
+{
+  mglGraph gr;
+  mglData dat(100);
+  char str[32];
+  for(int i=0;i<40;i++)
+  {
+    gr.NewFrame();     // start frame
+    gr.Box();          // some plotting
+    for(int j=0;j<dat.nx;j++)
+      dat.a[j]=sin(M_PI*j/dat.nx+M_PI*0.05*i);
+    gr.Plot(dat,"b");
+    gr.EndFrame();     // end frame
+    gr.WriteFrame();   // save frame
+  }
+  return 0;
+}
 @end verbatim
-The differences from the using of bitmap picture are: applying of the other class @code{mglGraphPS}, and writing to other format (function @code{WriteEPS()} instead of function @code{WritePNG()}). Moreover, there is no switching of the plot transparency @code{Alpha} since EPS format does not support it. Possibly I shall include transparency in future by program emulation.
 
-Classes @code{mglGraphZB} and @code{mglGraphPS} have some merits and demerits. Class @code{mglGraphZB} draws beautiful surface with transparency, smoothed colors and lightning, but the output picture is @emph{bitmap}, that leads to a bad scalability. On the contrary, class @code{mglGraphPS} creates vector file with excellent scalability. But file has large size (especially for surfaces), it does not support transparency and color smoothing. So, vector picture looks stylish but a bit angularly.
+Created files can be converted to movie by help of a lot of programs. For example, you can use ImageMagic (command @samp{convert frame*.jpg movie.mpg}), MPEG library, GIMP and so on.
+
+Finally, you can use @code{mglconv} tool for doing the same with MGL scripts (@pxref{Utilities}).
 
 @c ------------------------------------------------------------------
-@node Drawing in memory, Using QMathGL, Drawing to file, Basic usage
+@node Drawing in memory, Using QMathGL, Animation, Basic usage
 @subsection Drawing in memory
 
-The last way of MathGL using is the drawing in memory. Class @code{mglGraphZB} allows one  to create a bitmap picture in memory. Further this picture can be displayed in window by some window libraries (like wxWidgets, FLTK, Windows GDI and so on). For example, the code for drawing in wxWidget library looks like:
+The last way of MathGL using is the drawing in memory. Class @code{mglGraph} allows one  to create a bitmap picture in memory. Further this picture can be displayed in window by some window libraries (like wxWidgets, FLTK, Windows GDI and so on). For example, the code for drawing in wxWidget library looks like:
 @verbatim
-    void MyForm::OnPaint(wxPaintEvent& event)
-    {
-        int w,h,x,y;
-        GetClientSize(&w,&h);   // size of the picture
-        mglGraphZB gr(w,h);
-
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-
-        wxImage img(w,h,gr.GetBits(),true);
-        ToolBar->GetSize(&x,&y);    // gets a height of the toolbar if any
-        wxPaintDC dc(this);         // and draws it
-        dc.DrawBitmap(wxBitmap(img),0,y);
-    }
+void MyForm::OnPaint(wxPaintEvent& event)
+{
+  int w,h,x,y;
+  GetClientSize(&w,&h);   // size of the picture
+  mglGraph gr(w,h);
+
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);
+  sample(&gr,NULL);
+
+  wxImage img(w,h,gr.GetBits(),true);
+  ToolBar->GetSize(&x,&y);    // gets a height of the toolbar if any
+  wxPaintDC dc(this);         // and draws it
+  dc.DrawBitmap(wxBitmap(img),0,y);
+}
 @end verbatim
 The drawing in other libraries is most the same.
-@c Moreover, I excluded the support of TIFF and JPEG files from MathGL by default for compatibility with wxWidgets library.
 
 For example, FLTK code will look like
 @verbatim
-    void Fl_MyWidget::draw()
-    {
-        mglGraphZB gr(w(),h());
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-        fl_draw_image(gr.GetBits(), x(), y(), gr.GetWidth(), gr.GetHeight(), 3);
-    }
+void Fl_MyWidget::draw()
+{
+  mglGraph gr(w(),h());
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);
+  sample(&gr,NULL);
+  fl_draw_image(gr.GetBits(), x(), y(), gr.GetWidth(), gr.GetHeight(), 3);
+}
 @end verbatim
 Qt code will look like
 @verbatim
-    void MyWidget::paintEvent(QPaintEvent *)
-    {
-        mglGraphZB gr(w(),h());
-        gr.Alpha(true);         // draws something using MathGL
-        gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
-        sample(&gr,NULL);
-
-        // Qt don't support RGB format as is. So, let convert it to BGRN.
-        const uchar *bb = gr.GetBits();
-        register long i, w=gr.GetWidth(), h=gr.GetHeight();
-        *buf = new uchar[4*w*h];
-        for(i=0;i<w*h;i++)
-        {
-            (*buf)[4*i]   = bb[3*i+2];
-            (*buf)[4*i+1] = bb[3*i+1];
-            (*buf)[4*i+2] = bb[3*i];
-            (*buf)[4*i+3] = 255;
-        }
-        QPixmap pic = QPixmap::fromImage(QImage(*buf, w, h, QImage::Format_RGB32));
-
-        QPainter paint;
-        paint.begin(this);  paint.drawPixmap(0,0,pic);  paint.end();
-        delete []buf;
-    }
+void MyWidget::paintEvent(QPaintEvent *)
+{
+  mglGraph gr(w(),h());
+
+  gr.Alpha(true);         // draws something using MathGL
+  gr.Light(true);         gr.Light(0,mglPoint(1,0,-1));
+  sample(&gr,NULL);
+
+  // Qt don't support RGB format as is. So, let convert it to BGRN.
+  long w=gr.GetWidth(), h=gr.GetHeight();
+  unsigned char *buf = new uchar[4*w*h];
+  gr.GetBGRN(buf, 4*w*h)
+  QPixmap pic = QPixmap::fromImage(QImage(*buf, w, h, QImage::Format_RGB32));
+
+  QPainter paint;
+  paint.begin(this);  paint.drawPixmap(0,0,pic);  paint.end();
+  delete []buf;
+}
 @end verbatim
 
 @c ------------------------------------------------------------------
-@node Using QMathGL, , Drawing in memory, Basic usage
+@node Using QMathGL, MathGL and PyQt, Drawing in memory, Basic usage
 @subsection Using QMathGL
 
-MathGL have several interface widgets for different widget libraries. There are QMathGL for Qt, Fl_MathGL for FLTK in MathGL v.1.8. These classes provide control which display MathGL graphics. Unfortunately there is no uniform interface for widget classes because all libraries have slightly different set of functions, features and so on. However the usage of MathGL widgets is rather simple. Let me show it on the example of QMathGL.
+MathGL have several interface widgets for different widget libraries. There are QMathGL for Qt, Fl_MathGL for FLTK. These classes provide control which display MathGL graphics. Unfortunately there is no uniform interface for widget classes because all libraries have slightly different set of functions, features and so on. However the usage of MathGL widgets is rather simple. Let me show it on the example of QMathGL.
 
 First of all you have to define the drawing function or inherit a class from @code{mglDraw} class. After it just create a window and setup QMathGL instance as any other Qt widget:
 @verbatim
-    int main(int argc,char **argv)
-    {
-        QApplication a(argc,argv);
-        QMainWindow *Wnd = new QMainWindow;
-        Wnd->resize(650,480);  // for fill up the QMGL, menu and toolbars
-        Wnd->setWindowTitle(title);
-        // here I allow to scroll QMathGL -- the case 
-        // then user want to prepare huge picture
-        QScrollArea *scroll = new QScrollArea(Wnd);
-
-        // Create and setup QMathGL
-        QMathGL *QMGL = new QMathGL(Wnd);
-        QMGL->setPopup(popup); // if you want to setup popup menu for QMGL
-        QMGL->setDraw(sample, NULL);
-        // or use QMGL->setDraw(foo); for instance of class Foo:public mglDraw
-        QMGL->update();
-
-        // continue other setup (menu, toolbar and so on)
-        makeMenu();
-        scroll->setWidget(QMGL);
-        Wnd->setCentralWidget(scroll);
-        Wnd->show();
-        return a.exec();
-    }
+#include <QApplication>
+#include <QMainWindow>
+#include <QScrollArea>
+#include <mgl/qt.h>
+int main(int argc,char **argv)
+{
+  QApplication a(argc,argv);
+  QMainWindow *Wnd = new QMainWindow;
+  Wnd->resize(810,610);  // for fill up the QMGL, menu and toolbars
+  Wnd->setWindowTitle("QMathGL sample");
+  // here I allow to scroll QMathGL -- the case
+  // then user want to prepare huge picture
+  QScrollArea *scroll = new QScrollArea(Wnd);
+
+  // Create and setup QMathGL
+  QMathGL *QMGL = new QMathGL(Wnd);
+//QMGL->setPopup(popup); // if you want to setup popup menu for QMGL
+  QMGL->setDraw(sample);
+  // or use QMGL->setDraw(foo); for instance of class Foo:public mglDraw
+  QMGL->update();
+
+  // continue other setup (menu, toolbar and so on)
+  scroll->setWidget(QMGL);
+  Wnd->setCentralWidget(scroll);
+  Wnd->show();
+  return a.exec();
+}
+@end verbatim
+
+@c ------------------------------------------------------------------
+@node MathGL and PyQt, , Using QMathGL, Basic usage
+@subsection MathGL and PyQt
+
+Generally SWIG based classes (including the Python one) are the same as C++ classes. However, there are few tips for using MathGL with PyQt. Below I place a very simple python code which demonstrate how MathGL can be used with PyQt. This code is mostly written by Prof. Dr. Heino Falcke. You can just copy it to a file @code{mgl-pyqt-test.py} and execute it from python shell by command @code{execfile("mgl-pyqt-test.py")}
+
+@verbatim
+from PyQt4 import QtGui,QtCore
+from mathgl import *
+import sys
+app = QtGui.QApplication(sys.argv)
+qpointf=QtCore.QPointF()
+
+class hfQtPlot(QtGui.QWidget):
+    def __init__(self, parent=None):
+        QtGui.QWidget.__init__(self, parent)
+        self.img=(QtGui.QImage())
+    def setgraph(self,gr):
+        self.buffer='\t'
+        self.buffer=self.buffer.expandtabs(4*gr.GetWidth()*gr.GetHeight())
+        gr.GetBGRN(self.buffer,len(self.buffer))
+        self.img=QtGui.QImage(self.buffer, gr.GetWidth(),gr.GetHeight(),QtGui.QImage.Format_ARGB32)
+        self.update()
+    def paintEvent(self, event):
+        paint = QtGui.QPainter()
+        paint.begin(self)
+        paint.drawImage(qpointf,self.img)
+        paint.end()
+
+BackgroundColor=[1.0,1.0,1.0]
+size=100
+gr=mglGraph()
+y=mglData(size)
+#y.Modify("((0.7*cos(2*pi*(x+.2)*500)+0.3)*(rnd*0.5+0.5)+362.135+10000.)")
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+x=mglData(size)
+x.Modify("x^2");
+
+def plotpanel(gr,x,y,n):
+    gr.SubPlot(2,2,n)
+    gr.SetXRange(x)
+    gr.SetYRange(y)
+    gr.AdjustTicks()
+    gr.Axis()
+    gr.Box()
+    gr.Label("x","x-Axis",1)
+    gr.Label("y","y-Axis",1)
+    gr.ClearLegend()
+    gr.AddLegend("Legend: "+str(n),"k")
+    gr.Legend()
+    gr.Plot(x,y)
+
+
+gr.Clf(BackgroundColor[0],BackgroundColor[1],BackgroundColor[2])
+gr.SetPlotFactor(1.5)
+plotpanel(gr,x,y,0)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,1)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,2)
+y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
+plotpanel(gr,x,y,3)
+
+gr.WritePNG("test.png","Test Plot")
+
+qw = hfQtPlot()
+qw.show()
+qw.setgraph(gr)
+qw.raise_()
 @end verbatim
 
 
@@ -257,1104 +526,2931 @@ First of all you have to define the drawing function or inherit a class from @co
 @node Advanced usage, Data handling, Basic usage, Examples
 @section Advanced usage
 
-Now I show several non-obvious features of MathGL: several subplots in a single picture, curvilinear coordinates, text printing and so on. Generally you may miss this section at first reading, but I don't recommend it.
+Now I show several non-obvious features of MathGL: several subplots in a single picture, curvilinear coordinates, text printing and so on. Generally you may miss this section at first reading.
 
 @menu
-* Subplots::                    
-* Axis and grids::              
-* Curvilinear coordinates::     
-* Text printing example::       
-* Animation::                   
+* Subplots::
+* Axis and ticks::
+* Curvilinear coordinates::
+* Colorbars::
+* Bounding box::
+* Ternary axis::
+* Text features::
+* Legend sample::
+* Cutting sample::
 @end menu
 
 @c ------------------------------------------------------------------
-@node Subplots, Axis and grids, , Advanced usage
+@node Subplots, Axis and ticks, , Advanced usage
 @subsection Subplots
 
-Let me demonstrate possibilities of axes transformation. MathGL has the following functions: @code{SubPlot}, @code{InPlot}, @code{Aspect} and @code{Rotate} (@pxref{Transformation matrix}). The order of their calling is strictly determined. First, one changes the position of axes in image area (functions @code{SubPlot} and @code{InPlot}). After that one may rotate the plot (function @code{Rotate}). Finally, one may change aspects of axes (function @code{Aspect}). The following code illustrates the aforesaid it:
-@verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->SubPlot(2,2,0);
-        gr->Box();
-        gr->Puts(mglPoint(-1,1.1,1),"Just box","rL");
-        gr->InPlot(0.2,0.5,0.7,1);
-        gr->Box();
-        gr->Puts(mglPoint(0,1.2,1),"InPlot example");
-
-        gr->SubPlot(2,2,1);
-        gr->Rotate(60,40);
-        gr->Aspect(1,1,1);
-        gr->Box();
-        gr->Puts(mglPoint(1,1,1.5),"Rotate only","rR");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->Aspect(1,1,2);
-        gr->Box();
-        gr->Puts(mglPoint(0,0,2),"Aspect and Rotate");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->Aspect(1,2,2);
-        gr->Box();
-        gr->Puts(mglPoint(0,0,1.5),"Aspect in other direction");
-        return 0;
-    }
-@end verbatim
-Here I used function @code{Puts} for printing the text in arbitrary position of picture (@pxref{Text printing}). Text coordinates and size are connected with axes. However, text coordinates may be everywhere, including the outside the bounding box. I shall show its features later in @xref{Text printing example}.
+Let me demonstrate possibilities of plot positioning and rotation. MathGL has a set of functions: @code{SubPlot}, @code{InPlot}, @code{Title}, @code{Aspect} and @code{Rotate} and so on (see @ref{Subplots and rotation}). The order of their calling is strictly determined. First, one changes the position of plot in image area (functions @code{SubPlot}, @code{InPlot} and @code{MultiPlot}). Secondly, you can add the title of plot by @code{Title} function. After that one may rotate the plot (function @code{Rotate}). Finally, one may change aspects of axes (function @code{Aspect}). The following code illustrates the aforesaid it:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Box();
+  gr->Puts(mglPoint(-1,1.1),"Just box",":L");
+  gr->InPlot(0.2,0.5,0.7,1,false);  gr->Box();
+  gr->Puts(mglPoint(0,1.2),"InPlot example");
+  gr->SubPlot(2,2,1); gr->Title("Rotate only");
+  gr->Rotate(50,60);  gr->Box();
+  gr->SubPlot(2,2,2); gr->Title("Rotate and Aspect");
+  gr->Rotate(50,60);  gr->Aspect(1,1,2);  gr->Box();
+  gr->SubPlot(2,2,3); gr->Title("Aspect in other direction");
+  gr->Rotate(50,60);  gr->Aspect(1,2,2);  gr->Box();
+  return 0;
+}
+@end verbatim
+Here I used function @code{Puts} for printing the text in arbitrary position of picture (see @ref{Text printing}). Text coordinates and size are connected with axes. However, text coordinates may be everywhere, including the outside the bounding box. I'll show its features later in @ref{Text features}.
+
+@fig{png/aspect, Example of several subplots on the single picture.}
+
+More complicated sample show how to use most of positioning functions:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(3,2,0); gr->Title("StickPlot");
+  gr->StickPlot(3, 0, 20, 30);  gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->StickPlot(3, 1, 20, 30);  gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->StickPlot(3, 2, 20, 30);  gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->SubPlot(3,2,3,"");  gr->Title("ColumnPlot");
+  gr->ColumnPlot(3, 0); gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->ColumnPlot(3, 1); gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->ColumnPlot(3, 2); gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->SubPlot(3,2,4,"");  gr->Title("GridPlot");
+  gr->GridPlot(2, 2, 0);  gr->Box("r"); gr->Puts(mglPoint(0),"0","r");
+  gr->GridPlot(2, 2, 1);  gr->Box("g"); gr->Puts(mglPoint(0),"1","g");
+  gr->GridPlot(2, 2, 2);  gr->Box("b"); gr->Puts(mglPoint(0),"2","b");
+  gr->GridPlot(2, 2, 3);  gr->Box("m"); gr->Puts(mglPoint(0),"3","m");
+  gr->SubPlot(3,2,5,"");  gr->Title("InPlot");  gr->Box();
+  gr->InPlot(0.4, 1, 0.6, 1, true); gr->Box("r");
+  gr->MultiPlot(3,2,1, 2, 1,"");  gr->Title("MultiPlot"); gr->Box();
+  return 0;
+}
+@end verbatim
+
+@fig{png/inplot, Example for most of positioning functions.}
 
-@float
-@image{../png/sample1, 7cm}
-@caption{Example of several subplots on the single picture.}
-@end float
 
 @c ------------------------------------------------------------------
-@node Axis and grids, Curvilinear coordinates, Subplots, Advanced usage
-@subsection Axis and grids
+@node Axis and ticks, Curvilinear coordinates, Subplots, Advanced usage
+@subsection Axis and ticks
 
-MathGL library can draw not only the bounding box but also the axes, grids, labels and so on. The limits of axes and their origin (the point of intersection) are determined by function @code{Axis()}. Also you can use @code{XRange(), YRange(), ZRange()} functions (@pxref{Ranges (bounding box)}). Ticks on axis are specified by function @code{SetTicks} (@pxref{Ticks}). First argument the direction for each change will be applied. Second argument gives the step between ticks (if positive) or gives the number of ticks on the axis (if negative) or set to use logarithmic ticks (if zero). Third argument gives numbers of sub-ticks between ticks (default is zero). Last argument define the initial ticks position.
+MathGL library can draw not only the bounding box but also the axes, grids, labels and so on. The ranges of axes and their origin (the point of intersection) are determined by functions @code{SetRange()}, @code{SetRanges()}, @code{SetOrigin()} (see @ref{Ranges (bounding box)}). Ticks on axis are specified by function @code{SetTicks}, @code{SetTicksVal}, @code{SetTicksTime} (see @ref{Ticks}). But usually
 
 Function @code{Axis} draws axes. Its textual string shows in which directions the axis or axes will be drawn (by default @code{"xyz"}, function draws axes in all directions). Function @code{Grid} draws grid perpendicularly to specified directions. Example of axes and grid drawing is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->SubPlot(2,2,0);
-        gr->SetTicks('x', 0.4, 3);  // sets tick step to 0.5
-        gr->SetTicks('y', 0.4, 3);  // and draws 3 subticks
-        gr->Box();                  // should be after the ticks change
-        gr->Axis("xy");
-        gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Axis and grid");
-
-        gr->SetTicks('x');  gr->SetTicks('y'); // restore back
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(0,0,0));
-
-        gr->SubPlot(2,2,1);
-        gr->Rotate(60,40);
-        gr->Axis();
-        gr->Label('x',"x");
-        gr->Label('y',"y");
-        gr->Label('z',"z");
-        gr->Puts(mglPoint(0,0,1.5),"Axis and labels");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->SetTicks('x', 0.2); gr->SetTicks('y', 0.2);
-        gr->SetTicks('z', 0.2); // too low step of ticks
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(-1,-1,-1));
-        gr->Axis();
-        gr->Grid();
-        gr->Puts(mglPoint(0,0,1.5),"Shift origin and add grid");
-        gr->Puts(mglPoint(0,0,1.2),"(note, too many ticks)");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->SetTicks('x', -6);  // decrease the number of ticks
-        gr->SetTicks('y', -6);
-        gr->Axis("yz");
-        gr->Label('y',"Y axis",0);
-        gr->Label('z',"Z axis",0);
-        gr->Puts(mglPoint(0,0,1.5),"Remove X axis, and");
-        gr->Puts(mglPoint(0,0,1.2),"decrease number of ticks");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Title("Axis origin, Grid"); gr->SetOrigin(0,0);
+  gr->Axis(); gr->Grid(); gr->FPlot("x^3");
+
+  gr->SubPlot(2,2,1); gr->Title("2 axis");
+  gr->SetRanges(-1,1,-1,1); gr->SetOrigin(-1,-1,-1);  // first axis
+  gr->Axis(); gr->Label('y',"axis 1",0);  gr->FPlot("sin(pi*x)");
+  gr->SetRanges(0,1,0,1);   gr->SetOrigin(1,1,1);   // second axis
+  gr->Axis(); gr->Label('y',"axis 2",0);  gr->FPlot("cos(pi*x)");
+
+  gr->SubPlot(2,2,3); gr->Title("More axis");
+  gr->SetOrigin(NAN,NAN); gr->SetRange('x',-1,1);
+  gr->Axis(); gr->Label('x',"x",0); gr->Label('y',"y_1",0);
+  gr->FPlot("x^2","k");
+  gr->SetRanges(-1,1,-1,1); gr->SetOrigin(-1.3,-1); // second axis
+  gr->Axis("y","r");  gr->Label('y',"#r{y_2}",0.2);
+  gr->FPlot("x^3","r");
+
+  gr->SubPlot(2,2,2); gr->Title("4 segments, inverted axis");
+  gr->SetOrigin(0,0);
+  gr->InPlot(0.5,1,0.5,1);  gr->SetRanges(0,10,0,2);  gr->Axis();
+  gr->FPlot("sqrt(x/2)");   gr->Label('x',"W",1); gr->Label('y',"U",1);
+  gr->InPlot(0,0.5,0.5,1);  gr->SetRanges(1,0,0,2); gr->Axis("x");
+  gr->FPlot("sqrt(x)+x^3"); gr->Label('x',"\\tau",-1);
+  gr->InPlot(0.5,1,0,0.5);  gr->SetRanges(0,10,4,0);  gr->Axis("y");
+  gr->FPlot("x/4"); gr->Label('y',"L",-1);
+  gr->InPlot(0,0.5,0,0.5);  gr->SetRanges(1,0,4,0); gr->FPlot("4*x^2");
+  return 0;
+}
 @end verbatim
 
-This example shows the importance of the correct choosing of the number of ticks on axis. If tick step is too small then its text may overlap and becomes unreadable. This code has the example of @code{Label} function. It draws label for axis in specified direction. The text position on axis is specified by third argument of @code{Label} function. If it is positive then then text is drawn near the axis maximum, if negative then the same takes place near the minimum of axis, if zero - then at the center of axis.
+Note, that MathGL can draw not only single axis (which is default). But also several axis on the plot (see right plots). The idea is that the change of settings does not influence on the already drawn graphics. So, for 2-axes I setup the first axis and draw everything concerning it. Then I setup the second axis and draw things for the second axis. Generally, the similar idea allows one to draw rather complicated plot of 4 axis with different ranges (see bottom left plot).
 
-@float
-@image{../png/sample2, 7cm}
-@caption{Example of setting up axis range and axis ticks.}
-@end float
+@fig{png/axis, Example of axis.}
 
-@c ------------------------------------------------------------------
-@node Curvilinear coordinates, Text printing example, Axis and grids, Advanced usage
-@subsection Curvilinear coordinates
+Another MathGL feature is fine ticks tunning. By default (if it is not changed by @code{SetTicks} function), MathGL try to adjust ticks positioning, so that they looks most human readable. At this, MathGL try to extract common factor for too large or too small axis ranges, as well as for too narrow ranges. Last one is non-common notation and can be disabled by @code{SetTuneTicks} function.
 
+Also, one can specify its own ticks with arbitrary labels by help of @code{SetTicksVal} function. Or one can set ticks in time format. In last case MathGL will try to select optimal format for labels with automatic switching between years, months/days, hours/minutes/seconds or microseconds. However, you can specify its own time representation using formats described in @url{http://www.manpagez.com/man/3/strftime/}. Most common variants are @samp{%X} for national representation of time, @samp{%x} for national representation of date, @samp{%Y} for year with century.
 
-Now let use curvilinear coordinates. In difference from other systems of plot creation, MathGL uses textual formulas for connection of the old (data) and new (output) coordinates. This allows one to plot in arbitrary coordinates. The following code plots the line @var{y}=0, @var{z}=0 in Cartesian, polar, parabolic and spiral coordinates:
+The sample code, demonstrated ticks feature is
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData x(50),y(50),z(50);
-        y.Fill(0.5,0.5);
-        x.Fill(-1,1);           // creates data arrays
-
-        gr->Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(-1,1,-1));
-        gr->dz = 0.5;           // sets tick step to 0.5
-
-        gr->SubPlot(2,2,0);
-        gr->Rotate(60,40);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Cartesian");
-
-        gr->SubPlot(2,2,1);
-        gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)",0);
-        gr->Rotate(60,40);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Cylindrical");
-
-        gr->SubPlot(2,2,2);
-        gr->Rotate(60,40);
-        gr->SetFunc("2*y*x","y*y - x*x",0);
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Parabolic");
-
-        gr->SubPlot(2,2,3);
-        gr->Rotate(60,40);
-        gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)","x+z");
-        gr->Plot(x,y,z,"r2");
-        gr->Axis(); gr->Grid();
-        gr->Puts(mglPoint(0,1.3,1),"Spiral");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(3,2,0); gr->Title("Usual axis");  gr->Axis();
+  gr->SubPlot(3,2,1); gr->Title("Too big/small range");
+  gr->SetRanges(-1000,1000,0,0.001);  gr->Axis();
+  gr->SubPlot(3,2,3); gr->Title("Too narrow range");
+  gr->SetRanges(100,100.1,10,10.01);  gr->Axis();
+  gr->SubPlot(3,2,4); gr->Title("Disable ticks tuning");
+  gr->SetTuneTicks(0);  gr->Axis();
+
+  gr->SubPlot(3,2,2); gr->Title("Manual ticks");  gr->SetRanges(-M_PI,M_PI, 0, 2);
+  float val[]={-M_PI, -M_PI/2, 0, 0.886, M_PI/2, M_PI};
+  gr->SetTicksVal('x', mglData(6,val), "-\\pi\n-\\pi/2\n0\nx^*\n\\pi/2\n\\pi");
+  gr->Axis(); gr->Grid(); gr->FPlot("2*cos(x^2)^2", "r2");
+
+  gr->SubPlot(3,2,5); gr->Title("Time ticks");  gr->SetRange('x',0,3e5);
+  gr->SetTicksTime('x',0);  gr->Axis();
+  return 0;
+}
+@end verbatim
+
+@fig{png/ticks, Features of axis ticks.}
+
+The last sample I want to show in this subsection is Log-axis. From MathGL's point of vew, the log-axis is particular case of general curvilinear coordinates. So, we need first define new coordinates (see also @ref{Curvilinear coordinates}) by help of @code{SetFunc} or @code{SetCoor} functions. At this one should wary about proper axis range. So the code looks as following:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"<_");  gr->Title("Semi-log axis");
+  gr->SetRanges(0.01,100,-1,1); gr->SetFunc("lg(x)","");
+  gr->Axis(); gr->Grid("xy","g"); gr->FPlot("sin(1/x)");
+  gr->Label('x',"x",0); gr->Label('y', "y = sin 1/x",0);
+
+  gr->SubPlot(2,2,1,"<_");  gr->Title("Log-log axis");
+  gr->SetRanges(0.01,100,0.1,100);  gr->SetFunc("lg(x)","lg(y)");
+  gr->Axis(); gr->FPlot("sqrt(1+x^2)"); gr->Label('x',"x",0);
+  gr->Label('y', "y = \\sqrt{1+x^2}",0);
+
+  gr->SubPlot(2,2,2,"<_");  gr->Title("Minus-log axis");
+  gr->SetRanges(-100,-0.01,-100,-0.1);  gr->SetFunc("-lg(-x)","-lg(-y)");
+  gr->Axis(); gr->FPlot("-sqrt(1+x^2)");
+  gr->Label('x',"x",0); gr->Label('y', "y = -\\sqrt{1+x^2}",0);
+
+  gr->SubPlot(2,2,3,"<_");  gr->Title("Log-ticks");
+  gr->SetRanges(0.1,100,0,100); gr->SetFunc("sqrt(x)","");
+  gr->Axis(); gr->FPlot("x");
+  gr->Label('x',"x",1); gr->Label('y', "y = x",0);
+  return 0;
+}
 @end verbatim
 
-@float
-@image{../png/sample3, 7cm}
-@caption{Example of curvilinear coordinates}
-@end float
+@fig{png/loglog, Features of axis ticks.}
 
+You can see that MathGL automatically switch to log-ticks as we define log-axis formula (in difference from v.1.*). Moreover, it switch to log-ticks for any formula if axis range will be large enough (see right bottom plot). Another interesting feature is that you not necessary define usual log-axis (i.e. when coordinates are positive), but you can define ``minus-log'' axis when coordinate is negative (see left bottom plot).
 
 @c ------------------------------------------------------------------
-@node Text printing example, Animation, Curvilinear coordinates, Advanced usage
-@subsection Text printing example
+@node Curvilinear coordinates, Colorbars, Axis and ticks, Advanced usage
+@subsection Curvilinear coordinates
 
-MathGL prints text by vector font. There are functions for manual specifying of text position (like @code{Puts}) and for its automatic selection (like @code{Label}, @code{Legend} and so on). MathGL prints text always in specified position even if it lies outside the bounding box. The default size of font is specified by variables @var{FontSize} (@pxref{Font settings}). However, the actual size of output string depends on position of axes (depends on functions @code{SubPlot}, @code{InPlot}). The switching of the font style (italic, bold, wire and so on) can be done for the whole string (by function parameter) or inside the string. By default MathGL parses TeX-like commands for symbols and indexes (see @pxref{Font styles}). Example of MathGL font drawing is:
+As I noted in previous subsection, MathGL support curvilinear coordinates. In difference from other plotting programs and libraries, MathGL uses textual formulas for connection of the old (data) and new (output) coordinates. This allows one to plot in arbitrary coordinates. The following code plots the line @var{y}=0, @var{z}=0 in Cartesian, polar, parabolic and spiral coordinates:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        setlocale(LC_CTYPE, "ru_RU.cp1251");
-        gr->Puts(mglPoint(0,1),"Text can be in ASCII and in Unicode");
-        gr->Puts(mglPoint(0,0.6),"It can be \\wire{wire}, \\big{big} "
-            "or #r{colored}");
-        gr->Puts(mglPoint(0,0.2),"One can change style in string: "
-            "\\b{bold}, \\i{italic, \\b{both}}");
-        gr->Puts(mglPoint(0,-0.2),"Easy to \\a{overline} or "
-            "\\u{underline}");
-        gr->Puts(mglPoint(0,-0.6),"Easy to change indexes "
-            "^{up} _{down} @{center}");
-        gr->Puts(mglPoint(0,-1),"It parse TeX: \\int \\alpha \\cdot "
-            "\\sqrt3{sin(\\pi x)^2 + \\gamma_{i_k}} dx");
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SetOrigin(-1,1,-1);
+
+  gr->SubPlot(2,2,0); gr->Title("Cartesian"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)",0);
+  gr->SubPlot(2,2,1); gr->Title("Cylindrical"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("2*y*x","y*y - x*x",0);
+  gr->SubPlot(2,2,2); gr->Title("Parabolic"); gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+
+  gr->SetFunc("y*sin(pi*x)","y*cos(pi*x)","x+z");
+  gr->SubPlot(2,2,3); gr->Title("Spiral");  gr->Rotate(50,60);
+  gr->FPlot("2*t-1","0.5","0","r2");
+  gr->Axis(); gr->Grid();
+  gr->SetFunc(0,0,0); // set to default Cartesian
+  return 0;
+}
 @end verbatim
 
-@float
-@image{../png/sample4, 7cm}
-@caption{Example of text printing with different font effects}
-@end float
+@fig{png/curvcoor, Example of curvilinear coordinates}
+
+
+@c ------------------------------------------------------------------
+@node Colorbars, Bounding box, Curvilinear coordinates, Advanced usage
+@subsection Colorbars
+
+MathGL handle colorbar as special kind of axis. So, most of functions for axis and ticks setup will work for colorbar too. Colorbars can be in log-scale, and generally as arbitrary function scale; common factor of colorbar labels can be separated; and so on.
 
-Another example demonstrate the features of TeX formula parsing.
+But of course, there are differences -- colorbars usually located out of bounding box. At this, colorbars can be at subplot boundaries (by default), or at bounding box (if symbol @samp{I} is specified). Colorbars can handle sharp colors. And they can be located at arbitrary position too. The sample code, which demonstrate colorbar features is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->Puts(mglPoint(0), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+"
-            "\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", 0, -4);
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Title("Colorbar out of box"); gr->Box();
+  gr->Colorbar("<");  gr->Colorbar(">");
+  gr->Colorbar("_");  gr->Colorbar("^");
+
+  gr->SubPlot(2,2,1); gr->Title("Colorbar near box");   gr->Box();
+  gr->Colorbar("<I"); gr->Colorbar(">I");
+  gr->Colorbar("_I"); gr->Colorbar("^I");
+
+  gr->SubPlot(2,2,2); gr->Title("manual colors");
+  mglData a,v;  mgls_prepare2d(&a,0,&v);
+  gr->Box();  gr->ContD(v,a);
+  gr->Colorbar(v,"<");  gr->Colorbar(v,">");
+  gr->Colorbar(v,"_");  gr->Colorbar(v,"^");
+
+  gr->SubPlot(2,2,3); gr->Title("log-scale");
+  gr->SetRange('c',0.01,1e3);
+  gr->Colorbar(">",0.5,0);  gr->Puts(mglPoint(0,1.2),"Normal scale");
+  gr->SetFunc("","","","lg(c)");
+  gr->Colorbar(">");    gr->Puts(mglPoint(1.3,1.2),"Log scale");
+  return 0;
+}
 @end verbatim
 
-@float
-@image{../png/samplee, 7cm}
-@caption{Example of TeX formula parsing}
-@end float
+@fig{png/colorbar, Example of colorbars}
+
+
+@c ------------------------------------------------------------------
+@node Bounding box, Ternary axis, Colorbars, Advanced usage
+@subsection Bounding box
 
-Finally you can change font during execution (this work well for mglGraphZB class only).
+Box around the plot is rather useful thing because it allows one to: see the plot boundaries, and better estimate points position since box contain another set of ticks. MathGL provide special function for drawing such box -- @code{Box()} function. By default, it draw black or white box with ticks (color depend on transparency type, see @ref{Types of transparency}). However, you can change the color of box, or add drawing of rectangles at rear faces of box. Also you can disable ticks drawing, but I don't know why anybody will want it. The sample code, which demonstrate @code{Box()} features is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        float h=1.1, d=0.25;
-        gr->LoadFont("STIX");       gr->Puts(mglPoint(0,h), "default font (STIX)");
-        gr->LoadFont("adventor");   gr->Puts(mglPoint(0,h-d), "adventor font");
-        gr->LoadFont("bonum");      gr->Puts(mglPoint(0,h-2*d), "bonum font");
-        gr->LoadFont("chorus");     gr->Puts(mglPoint(0,h-3*d), "chorus font");
-        gr->LoadFont("cursor");     gr->Puts(mglPoint(0,h-4*d), "cursor font");
-        gr->LoadFont("heros");      gr->Puts(mglPoint(0,h-5*d), "heros font");
-        gr->LoadFont("heroscn");    gr->Puts(mglPoint(0,h-6*d), "heroscn font");
-        gr->LoadFont("pagella");    gr->Puts(mglPoint(0,h-7*d), "pagella font");
-        gr->LoadFont("schola");     gr->Puts(mglPoint(0,h-8*d), "schola font");
-        gr->LoadFont("termes");     gr->Puts(mglPoint(0,h-9*d), "termes font");
-    }
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0); gr->Title("Box (default)"); gr->Rotate(50,60);
+  gr->Box();
+  gr->SubPlot(2,2,1); gr->Title("colored");   gr->Rotate(50,60);
+  gr->Box("r");
+  gr->SubPlot(2,2,2); gr->Title("with faces");  gr->Rotate(50,60);
+  gr->Box("@");
+  gr->SubPlot(2,2,3); gr->Title("both");  gr->Rotate(50,60);
+  gr->Box("@cm");
+  return 0;
+}
 @end verbatim
 
-@float
-@image{../png/fonts, 7cm}
-@caption{Example of font face changing.}
-@end float
+@fig{png/box, Example of Box()}
+
 
 @c ------------------------------------------------------------------
-@node Animation, , Text printing example, Advanced usage
-@subsection Animation
+@node Ternary axis, Text features, Bounding box, Advanced usage
+@subsection Ternary axis
+
+There are another unusual axis types which are supported by MathGL. These are ternary and quaternary axis. Ternary axis is special axis of 3 coordinates @var{a}, @var{b}, @var{c} which satisfy relation @var{a}+@var{b}+@var{c}=1. Correspondingly, quaternary axis is special axis of 4 coordinates @var{a}, @var{b}, @var{c}, @var{d} which satisfy relation @var{a}+@var{b}+@var{c}+@var{d}=1.
+
+Generally speaking, only 2 of coordinates (3 for quaternary) are independent. So, MathGL just introduce some special transformation formulas which treat @var{a} as @samp{x}, @var{b} as @samp{y} (and @var{c} as @samp{z} for quaternary). As result, all plotting functions (curves, surfaces, contours and so on) work as usual, but in new axis. You should use @code{Ternary} function for switching to ternary/quaternary coordinates. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SetRanges(0,1,0,1,0,1);
+  mglData x(50),y(50),z(50),rx(10),ry(10), a(20,30);
+  a.Modify("30*x*y*(1-x-y)^2*(x+y<1)");
+  x.Modify("0.25*(1+cos(2*pi*x))");
+  y.Modify("0.25*(1+sin(2*pi*x))");
+  rx.Modify("rnd"); ry.Modify("(1-v)*rnd",rx);
+  z.Modify("x");
+
+  gr->SubPlot(2,2,0); gr->Title("Ordinary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('x',"B",1); gr->Label('y',"C",1); gr->Label('z',"Z",1);
+
+  gr->SubPlot(2,2,1); gr->Title("Ternary axis (x+y+t=1)");
+  gr->Ternary(1);
+  gr->Plot(x,y,"r2"); gr->Plot(rx,ry,"q^ ");  gr->Cont(a,"BbcyrR");
+  gr->Line(mglPoint(0.5,0), mglPoint(0,0.75), "g2");
+  gr->Axis(); gr->Grid("xyz","B;");
+  gr->Label('x',"B"); gr->Label('y',"C"); gr->Label('t',"A");
+
+  gr->SubPlot(2,2,2); gr->Title("Quaternary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Ternary(2);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('t',"A",1); gr->Label('x',"B",1);
+  gr->Label('y',"C",1); gr->Label('z',"D",1);
+
+  gr->SubPlot(2,2,3); gr->Title("Ternary axis 3D");
+  gr->Rotate(50,60);    gr->Light(true);
+  gr->Ternary(1);
+  gr->Plot(x,y,z,"r2"); gr->Surf(a,"BbcyrR#");
+  gr->Axis(); gr->Grid(); gr->Box();
+  gr->Label('t',"A",1); gr->Label('x',"B",1);
+  gr->Label('y',"C",1); gr->Label('z',"Z",1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/ternary, Example of colorbars}
 
-You can make animation by several methods in MathGL: by export in animated GIF, or by save each frame in separate file (usually JPEG) and convert these files into movie. Let me show both methods.
+@c ------------------------------------------------------------------
+@node Text features, Legend sample, Ternary axis, Advanced usage
+@subsection Text features
+
+MathGL prints text by vector font. There are functions for manual specifying of text position (like @code{Puts}) and for its automatic selection (like @code{Label}, @code{Legend} and so on). MathGL prints text always in specified position even if it lies outside the bounding box. The default size of font is specified by functions @var{SetFontSize*} (see @ref{Font settings}). However, the actual size of output string depends on subplot size (depends on functions @code{SubPlot}, @code{InPlot}). The switching of the font style (italic, bold, wire and so on) can be done for the whole string (by function parameter) or inside the string. By default MathGL parses TeX-like commands for symbols and indexes (see @ref{Font styles}).
+
+Text can be printed as usual one (from left to right), along some direction (rotated text), or along a curve. Text can be printed on several lines, divided by new line symbol @samp{\n}.
+
+Example of MathGL font drawing is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"");
+  gr->Putsw(mglPoint(0,1),L"Text can be in ASCII and in Unicode");
+  gr->Puts(mglPoint(0,0.6),"It can be \\wire{wire}, \\big{big} or #r{colored}");
+  gr->Puts(mglPoint(0,0.2),"One can change style in string: "
+  "\\b{bold}, \\i{italic, \\b{both}}");
+  gr->Puts(mglPoint(0,-0.2),"Easy to \\a{overline} or "
+  "\\u{underline}");
+  gr->Puts(mglPoint(0,-0.6),"Easy to change indexes ^{up} _{down} @{center}");
+  gr->Puts(mglPoint(0,-1),"It parse TeX: \\int \\alpha \\cdot "
+  "\\sqrt3{sin(\\pi x)^2 + \\gamma_{i_k}} dx");
+
+  gr->SubPlot(2,2,1,"");
+  gr->Puts(mglPoint(0,0.5), "\\sqrt{\\frac{\\alpha^{\\gamma^2}+\\overset 1{\\big\\infty}}{\\sqrt3{2+b}}}", "@", -4);
+  gr->Puts(mglPoint(0,-0.5),"Text can be printed\non several lines");
+
+  gr->SubPlot(2,2,2,"");
+  mglData y;  mgls_prepare1d(&y);
+  gr->Box();  gr->Plot(y.SubData(-1,0));
+  gr->Text(y,"This is very very long string drawn along a curve",":k");
+  gr->Text(y,"Another string drawn above a curve","T:r");
+
+  gr->SubPlot(2,2,3,"");
+  gr->Line(mglPoint(-1,-1),mglPoint(1,-1),"rA");
+  gr->Puts(mglPoint(0,-1),mglPoint(1,-1),"Horizontal");
+  gr->Line(mglPoint(-1,-1),mglPoint(1,1),"rA");
+  gr->Puts(mglPoint(0,0),mglPoint(1,1),"At angle","@");
+  gr->Line(mglPoint(-1,-1),mglPoint(-1,1),"rA");
+  gr->Puts(mglPoint(-1,0),mglPoint(-1,1),"Vertical");
+  return 0;
+}
+@end verbatim
+
+@fig{png/text, Example of text printing}
 
-The simplest methods is making animated GIF. There are 3 steps: (1) open GIF file by @code{StartGIF()} function; (2) create the frames by calling @code{NewFrame()} before and @code{EndFrame()} after plotting; (3) close GIF by @code{CloseGIF()} function. So the simplest code for ``running'' sinusoid will look like this:
+@c ------------------------------------------------------------------
+@node Legend sample, Cutting sample, Text features, Advanced usage
+@subsection Legend sample
+
+Legend is one of standard ways to show plot annotations. Basically you need to connect the plot style (line style, marker and color) with some text. In MathGL, you can do it by 2 methods: manually using @code{AddLegend} function (see @ref{Legend}); or use @samp{legend} option (see @ref{Command options}), which will use last plot style. In both cases, legend entries will be added into internal accumulator, which later used for legend drawing itself. @code{ClearLegend} function allow you to remove all saved legend entries.
+
+There are 2 features. If plot style is empty then text will be printed without indent. If you want to plot the text with indent but without plot sample then you need to use space @samp{ } as plot style. Such style @samp{ } will draw a plot sample (line with marker(s)) which is invisible line (i.e. nothing) and print the text with indent as usual one.
+
+Function @code{Legend} draw legend on the plot. The position of the legend can be selected automatic or manually. You can change the size and style of text labels, as well as setup the plot sample. The sample code demonstrating legend features is:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData dat(100);
-        char str[32];
-        gr->StartGIF("sample.gif");
-        for(int i=0;i<100;i++)
-        {
-            gr->NewFrame();     // start frame
-            gr->Box();          // some plotting
-            sprintf(str,"sin(pi*x+%g*pi)",0.02*i);
-            dat.Modify(str);
-            gr->Plot(dat,"b");
-            gr->EndFrame();     // end frame
-        }
-        gr->CloseGIF();
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  gr->AddLegend("sin(\\pi {x^2})","b");
+  gr->AddLegend("sin(\\pi x)","g*");
+  gr->AddLegend("sin(\\pi \\sqrt{x})","rd");
+  gr->AddLegend("just text"," ");
+  gr->AddLegend("no indent for this","");
+
+  gr->SubPlot(2,2,0,""); gr->Title("Legend (default)");
+  gr->Box();  gr->Legend();
+
+  gr->Legend(3,"A#");
+  gr->Puts(mglPoint(0.75,0.65),"Absolute position","A");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("coloring");  gr->Box();
+  gr->Legend(0,"r#"); gr->Legend(1,"Wb#");  gr->Legend(2,"ygr#");
+
+  gr->SubPlot(2,2,3,"");  gr->Title("manual position");
+  gr->Box();  gr->Legend(0.5,0.5);
+  return 0;
+}
 @end verbatim
 
-The second way is saving each frame in separate file (usually JPEG) and later make the movie from them. MathGL have special function for saving frames -- it is @code{WriteFrame()}. This function save each frame with automatic name @samp{frame0001.jpg, frame0002.jpg} and so on. Here prefix @samp{frame} is defined by @var{PlotId} variable of @code{mglGraph} class. So the similar code will look like this:
+@fig{png/legend, Example of legend}
+
+@c ------------------------------------------------------------------
+@node Cutting sample, , Legend sample, Advanced usage
+@subsection Cutting sample
+
+The last common thing which I want to show in this section is how one can cut off points from plot. There are 4 mechanism for that.
+@itemize @bullet
+@item
+You can set one of coordinate to NAN value. All points with NAN values will be omitted.
+
+@item
+You can enable cutting at edges by @code{SetCut} function. As result all points out of bounding box will be omitted.
+
+@item
+You can set cutting box by @code{SetCutBox} function. All points inside this box will be omitted.
+
+@item
+You can define cutting formula by @code{SetCutOff} function. All points for which the value of formula is nonzero will be omitted. Note, that this is the slowest variant.
+@end itemize
+
+Below I place the code which demonstrate last 3 possibilities:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData dat(100);
-        char str[32];
-        for(int i=0;i<100;i++)
-        {
-            gr->NewFrame();     // start frame
-            gr->Box();          // some plotting
-            sprintf(str,"sin(pi*x+%g*pi)",0.02*i);
-            dat.Modify(str);
-            gr->Plot(dat,"b");
-            gr->EndFrame();     // end frame
-            gr->WriteFrame();   // save frame
-        }
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  mglData a,c,v(1); mgls_prepare2d(&a); mgls_prepare3d(&c); v.a[0]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("Cut on (default)");
+  gr->Rotate(50,60);  gr->Light(true);
+  gr->Box();  gr->Surf(a,"","zrange -1 0.5");
+
+  gr->SubPlot(2,2,1); gr->Title("Cut off");   gr->Rotate(50,60);
+  gr->Box();  gr->Surf(a,"","zrange -1 0.5; cut off");
+
+  gr->SubPlot(2,2,2); gr->Title("Cut in box");  gr->Rotate(50,60);
+  gr->SetCutBox(mglPoint(0,-1,-1), mglPoint(1,0,1.1));
+  gr->Alpha(true);  gr->Box();  gr->Surf3(c);
+  gr->SetCutBox(mglPoint(0), mglPoint(0));  // switch it off
+
+  gr->SubPlot(2,2,3); gr->Title("Cut by formula");  gr->Rotate(50,60);
+  gr->CutOff("(z>(x+0.5*y-1)^2-1) & (z>(x-0.5*y-1)^2-1)");
+  gr->Box();  gr->Surf3(c); gr->CutOff(""); // switch it off
+  return 0;
+}
 @end verbatim
 
-Created files can be converted to movie by help of a lot of programs. For example, you can use ImageMagic (command @samp{convert frame*.jpg movie.mpg}), MPEG library, GIMP and so on.
+@fig{png/cut, Example of point cutting}
+
 
-Finally, you can use @code{mgl2gif} tool for doing the same with MGL scripts (@pxref{Utilities}).
 
 @c ------------------------------------------------------------------
 @node Data handling, Data plotting, Advanced usage, Examples
 @section Data handling
 
-Class @code{mglData} contains all functions for the data handling in MathGL (@pxref{mglData class}). There are several matters why I use class @code{mglData} but not a single array: it does not depend on type of data (float or double), sizes of data arrays are kept with data, memory working is simpler and safer.
+Class @code{mglData} contains all functions for the data handling in MathGL (@pxref{Data processing}). There are several matters why I use class @code{mglData} but not a single array: it does not depend on type of data (float or double), sizes of data arrays are kept with data, memory working is simpler and safer.
 
 @menu
-* Array creation::              
-* Data changing::               
+* Array creation::
+* Linking array::
+* Change data::
 @end menu
 
 @c ------------------------------------------------------------------
-@node Array creation, Data changing, , Data handling
+@node Array creation, Change data, , Data handling
 @subsection Array creation
 
+There are many ways in MathGL how data arrays can be created and filled.
+
 One can put the data in @code{mglData} instance by several ways. Let us do it for sinus function:
 @itemize @bullet
 @item
 one can create external array, fill it and put to @code{mglData} variable
 @verbatim
-    double *a = new double[50];
-    for(int i=0;i<50;i++)   a[i] = sin(M_PI*i/49.);
+  double *a = new double[50];
+  for(int i=0;i<50;i++)   a[i] = sin(M_PI*i/49.);
 
-    mglData y;
-    y.Set(a,50);
+  mglData y;
+  y.Set(a,50);
 @end verbatim
 
 @item
 another way is to create @code{mglData} instance of the desired size and then to work directly with data in this variable
 @verbatim
-    mglData y(50);
-    for(int i=0;i<50;i++)   y.a[i] = sin(M_PI*i/49.);
+  mglData y(50);
+  for(int i=0;i<50;i++)   y.a[i] = sin(M_PI*i/49.);
 @end verbatim
 
 @item
 next way is to fill the data in @code{mglData} instance by textual formula with the help of @code{Modify()} function
 @verbatim
-    mglData y(50);
-    y.Modify("sin(pi*x)");
+  mglData y(50);
+  y.Modify("sin(pi*x)");
 @end verbatim
 
 @item
 or one may fill the array in some interval and modify it later
 @verbatim
-    mglData y(50);
-    y.Fill(0,M_PI);
-    y.Modify("sin(u)");
+  mglData y(50);
+  y.Fill(0,M_PI);
+  y.Modify("sin(u)");
 @end verbatim
 
 @item
 finally it can be loaded from file
 @verbatim
-    FILE *fp=fopen("sin.dat","wt");   // create file first
-    for(int i=0;i<50;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
-    fclose(fp);
+  FILE *fp=fopen("sin.dat","wt");   // create file first
+  for(int i=0;i<50;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
+  fclose(fp);
 
-    mglData y("sin.dat");             // load it
+  mglData y("sin.dat");             // load it
 @end verbatim
+At this you can use textual or HDF files, as well as import values from bitmap image (PNG is supported right now).
 
 @item
 at this one can read only part of data
 @verbatim
-    FILE *fp-fopen("sin.dat","wt");   // create large file first
-    for(int i=0;i<70;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
-    fclose(fp);
+  FILE *fp-fopen("sin.dat","wt");   // create large file first
+  for(int i=0;i<70;i++)   fprintf(fp,"%g\n",sin(M_PI*i/49.));
+  fclose(fp);
 
-    mglData y;
-    y.Read("sin.dat",50);             // load it
+  mglData y;
+  y.Read("sin.dat",50);             // load it
 @end verbatim
 @end itemize
 
 Creation of 2d- and 3d-arrays is mostly the same. But one should keep in mind that class @code{mglData} uses flat data representation. For example, matrix 30*40 is presented as flat (1d-) array with length 30*40=1200 (nx=30, ny=40). The element with indexes @{i,j@} is a[i+nx*j]. So for 2d array we have:
 @verbatim
-    mglData z(30,40);
-    for(int i=0;i<30;i++)   for(int j=0;j<40;j++)
-        z.a[i+30*j] = sin(M_PI*i/29.)*sin(M_PI*j/39.);
+  mglData z(30,40);
+  for(int i=0;i<30;i++)   for(int j=0;j<40;j++)
+    z.a[i+30*j] = sin(M_PI*i/29.)*sin(M_PI*j/39.);
 @end verbatim
 or by using @code{Modify()} function
 @verbatim
-    mglData z(30,40);
-    z.Modify("sin(pi*x)*cos(pi*y)");
+  mglData z(30,40);
+  z.Modify("sin(pi*x)*cos(pi*y)");
 @end verbatim
 
-The only non-obvious thing here is using multidimensional arrays in C/C++, i.e. arrays defined like @code{float dat[40][30];}. Since, formaly this arrays element @code{dat[i]} can address the memory in arbitrary place you should use the proper function to convert such arrays to @code{mglData} object. For C++ this is functions like @code{mglData::Set(float **dat, int N1, int N2);}. For C this is functions like @code{mgl_data_set_float2(HMDT d, const float **dat, int N1, int N2);}. At this, you should keep in mind that @code{nx=N2} and @code{ny=N1} after conversion.
+The only non-obvious thing here is using multidimensional arrays in C/C++, i.e. arrays defined like @code{float dat[40][30];}. Since, formally these elements @code{dat[i]} can address the memory in arbitrary place you should use the proper function to convert such arrays to @code{mglData} object. For C++ this is functions like @code{mglData::Set(float **dat, int N1, int N2);}. For C this is functions like @code{mgl_data_set_float2(HMDT d, const float **dat, int N1, int N2);}. At this, you should keep in mind that @code{nx=N2} and @code{ny=N1} after conversion.
 
 @c ------------------------------------------------------------------
-@node Data changing, , Array creation, Data handling
-@subsection Data changing
+@node Linking array, Change data, Array creation, Data handling
+@subsection Linking array
 
-MathGL has functions for data processing: differentiating, integrating, smoothing and so on (for more detail, @pxref{mglData class}). Let us consider some examples. The simplest ones are integration and differentiation. The direction in which operation will be performed is specified by textual string, which may contain symbols @samp{x}, @samp{y} or @samp{z}. For example, the call of @code{Diff("x")} will differentiate data along @samp{x} direction; the call of @code{Integral("xy")} perform the double integration of data along @samp{x} and @samp{y} directions; the call of @code{Diff2("xyz")} will apply 3d Laplace operator to data and so on. Example of this operations on 2d array a=x*y is presented in code:
-@verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData a(30,40);   a.Modify("x*y");
-        gr->Axis(mglPoint(0,0,0),mglPoint(1,1,1));
-        gr->SubPlot(2,2,0); gr->Rotate(60,40);
-        gr->Surf(a);        gr->Box();
-        gr->Puts(mglPoint(0.7,1,1.2),"a(x,y)");
-        gr->SubPlot(2,2,1); gr->Rotate(60,40);
-        a.Diff("x");        gr->Surf(a);      gr->Box();
-        gr->Puts(mglPoint(0.7,1,1.2),"da/dx");
-        gr->SubPlot(2,2,2); gr->Rotate(60,40);
-        a.Integral("xy");   gr->Surf(a);      gr->Box();
-        gr->Puts(mglPoint(0.7,1,1.2),"\\int da/dx dxdy");
-        gr->SubPlot(2,2,3); gr->Rotate(60,40);
-        a.Diff2("y");       gr->Surf(a);      gr->Box();
-        gr->Puts(mglPoint(0.7,1,1.2),"\\int {d^2}a/dxdy dx");
-        return 0;
-    }
-@end verbatim
+Sometimes the data arrays are so large, that one couldn't' copy its values to another array (i.e. into mglData). In this case, he can define its own class derived from @code{mglDataA} (see @ref{mglDataA class}) or can use @code{Link} function.
 
-@float
-@image{../png/sample6, 7cm}
-@caption{Example of data differentiation and integration}
-@end float
+In last case, MathGL just save the link to an external data array, but not copy it. You should provide the existence of this data array for whole time during which MathGL can use it. Another point is that MathGL will automatically create new array if you'll try to modify data values by any of @code{mglData} functions. So, you should use only function with @code{const} modifier if you want still using link to the original data array.
 
-Data smoothing (function @code{Smooth()}) is more interesting and important. This function has 2 main arguments: type of smoothing and its direction. Now 4 methods are supported: @code{SMOOTH_NONE} does nothing for delta=0 or approaches data to zero with the step delta, @code{SMOOTH_LINE_3} linear averaging by 3 points, @code{SMOOTH_LINE_5} linear averaging by 5 points, @code{SMOOTH_QUAD_5} quadratic averaging by 5 points. Let me demonstrate it for 1d case:
+Creating the link is rather simple -- just the same as using @code{Set} function
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData y0(30),y1,y2,y3;
-        y0.Modify("0.4*sin(2*pi*x)+0.3*cos(3*pi*x)-0.4*sin(4*pi*x)+0.2*rnd");
-
-        y1=y0;  y1.Smooth(SMOOTH_LINE_3);
-        y2=y0;  y2.Smooth(SMOOTH_LINE_5);
-        y3=y0;  y3.Smooth(SMOOTH_QUAD_5);
-
-        gr->Plot(y0,"k");   gr->AddLegend("NONE","k");
-        gr->Plot(y1,"r");   gr->AddLegend("LINE_3","r");
-        gr->Plot(y2,"g");   gr->AddLegend("LINE_5","g");
-        gr->Plot(y3,"b");   gr->AddLegend("QUAD_5","b");
-        gr->Legend();       gr->Box();
-        return 0;
-    }
+  double *a = new double[50];
+  for(int i=0;i<50;i++)   a[i] = sin(M_PI*i/49.);
+
+  mglData y;
+  y.Link(a,50);
 @end verbatim
 
-@float
-@image{../png/sample7, 7cm}
-@caption{Example of data smoothing}
-@end float
+@c ------------------------------------------------------------------
+@node Change data, , Linking array, Data handling
+@subsection Change data
+
+MathGL has functions for data processing: differentiating, integrating, smoothing and so on (for more detail, see @ref{Data processing}). Let us consider some examples. The simplest ones are integration and differentiation. The direction in which operation will be performed is specified by textual string, which may contain symbols @samp{x}, @samp{y} or @samp{z}. For example, the call of @code{Diff("x")} will differentiate data along @samp{x} direction; the call of @code{Integral("xy")} perform the double integration of data along @samp{x} and @samp{y} directions; the call of @code{Diff2("xyz")} will apply 3d Laplace operator to data and so on. Example of this operations on 2d array a=x*y is presented in code:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SetRanges(0,1,0,1,0,1);
+  mglData a(30,40); a.Modify("x*y");
+  gr->SubPlot(2,2,0); gr->Rotate(60,40);
+  gr->Surf(a);    gr->Box();
+  gr->Puts(mglPoint(0.7,1,1.2),"a(x,y)");
+  gr->SubPlot(2,2,1); gr->Rotate(60,40);
+  a.Diff("x");    gr->Surf(a);  gr->Box();
+  gr->Puts(mglPoint(0.7,1,1.2),"da/dx");
+  gr->SubPlot(2,2,2); gr->Rotate(60,40);
+  a.Integral("xy"); gr->Surf(a);  gr->Box();
+  gr->Puts(mglPoint(0.7,1,1.2),"\\int da/dx dxdy");
+  gr->SubPlot(2,2,3); gr->Rotate(60,40);
+  a.Diff2("y"); gr->Surf(a);  gr->Box();
+  gr->Puts(mglPoint(0.7,1,1.2),"\\int {d^2}a/dxdy dx");
+  return 0;
+}
+@end verbatim
+
+@fig{png/dat_diff, Example of data differentiation and integration}
+
+Data smoothing (function @code{Smooth()}) is more interesting and important. This function has single argument which define type of smoothing and its direction. Now 3 methods are supported: @samp{3} -- linear averaging by 3 points, @samp{5} -- linear averaging by 5 points, and default one -- quadratic averaging by 5 points.
+
+MathGL also have some amazing functions which is not so important for data processing as useful for data plotting. There are functions for finding envelope (useful for plotting rapidly oscillating data), for data sewing (useful to removing jumps on the phase), for data resizing (interpolation). Let me demonstrate it:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->SubPlot(2,2,0,"");  gr->Title("Envelop sample");
+  mglData d1(1000); gr->Fill(d1,"exp(-8*x^2)*sin(10*pi*x)");
+  gr->Axis();     gr->Plot(d1, "b");
+  d1.Envelop('x');  gr->Plot(d1, "r");
+
+  gr->SubPlot(2,2,1,"");  gr->Title("Smooth sample");
+  mglData y0(30),y1,y2,y3;
+  gr->SetRanges(0,1,0,1);
+  gr->Fill(y0, "0.4*sin(pi*x) + 0.3*cos(1.5*pi*x) - 0.4*sin(2*pi*x)+0.5*rnd");
+
+  y1=y0;  y1.Smooth("x3");
+  y2=y0;  y2.Smooth("x5");
+  y3=y0;  y3.Smooth("x");
+
+  gr->Plot(y0,"{m7}:s", "legend 'none'"); //gr->AddLegend("none","k");
+  gr->Plot(y1,"r", "legend ''3' style'");
+  gr->Plot(y2,"g", "legend ''5' style'");
+  gr->Plot(y3,"b", "legend 'default'");
+  gr->Legend();   gr->Box();
+
+  gr->SubPlot(2,2,2);   gr->Title("Sew sample");
+  mglData d2(100, 100); gr->Fill(d2, "mod((y^2-(1-x)^2)/2,0.1)");
+  gr->Rotate(50, 60);   gr->Light(true);  gr->Alpha(true);
+  gr->Box();            gr->Surf(d2, "b");
+  d2.Sew("xy", 0.1);  gr->Surf(d2, "r");
+
+  gr->SubPlot(2,2,3);   gr->Title("Resize sample (interpolation)");
+  mglData x0(10), v0(10), x1, v1;
+  gr->Fill(x0,"rnd");     gr->Fill(v0,"rnd");
+  x1 = x0.Resize(100);    v1 = v0.Resize(100);
+  gr->Plot(x0,v0,"b+ ");  gr->Plot(x1,v1,"r-");
+  gr->Label(x0,v0,"%n");
+  return 0;
+}
+@end verbatim
+
+@fig{png/dat_extra, Example of data smoothing}
+
+Finally one can create new data arrays on base of the existing one: extract slice, row or column of data (@code{SubData()}), summarize along a direction(s) (@code{Sum()}), find distribution of data elements (@code{Hist()}) and so on.
 
-Finally one can create new data arrays on base of the existing one: extract slice, row or column of data (@code{SubData()}), summarize along some of direction(s) (@code{Sum()}), find distribution of data elements (@code{Hist()}). Note, that all these functions are not thread-safe because they use static internal variable for output array. In particular, the using of several of them in arguments of the same function will lead to unpredictable result.
 
 @c ------------------------------------------------------------------
-@node Data plotting, C/Fortran interface, Data handling, Examples
+@node Data plotting, 1D samples, Data handling, Examples
 @section Data plotting
 
-Let me now show how to plot the data. MathGL generally has 2 types of plotting functions. Simple variant requires a single data array for plotting, other data (coordinates) are considered uniformly distributed in interval @var{Min}*@var{Max}. Second variant requires data arrays for all coordinates. It allows one to plot rather complex multivalent curves and surfaces (in case of parametric dependencies). Argument setting to default values allows one to plot data in standard form. Manual arguments setting gives possibility for fine tuning of colors, positions and view of graphics. Note, that the call of drawing function adds something to picture but does not clear the previous plots (as it does in Matlab). Another difference from Matlab is that all setup (like transparency, lightning, axis borders and so on) must be specified @strong{before} plotting functions.
-
-@menu
-* Plots for 1D data::           
-* Plots for 2D data::           
-* Plots for 3D data::           
-* Surface transparency::        
-@end menu
+Let me now show how to plot the data. Next section will give much more examples for all plotting functions. Here I just show some basics. MathGL generally has 2 types of plotting functions. Simple variant requires a single data array for plotting, other data (coordinates) are considered uniformly distributed in axis range. Second variant requires data arrays for all coordinates. It allows one to plot rather complex multivalent curves and surfaces (in case of parametric dependencies). Usually each function have one textual argument for plot style and another textual argument for options (see @ref{Command options}).
 
-@c ------------------------------------------------------------------
-@node Plots for 1D data, Plots for 2D data, , Data plotting
-@subsection Plots for 1D data
+Note, that the call of drawing function adds something to picture but does not clear the previous plots (as it does in Matlab). Another difference from Matlab is that all setup (like transparency, lightning, axis borders and so on) must be specified @strong{before} plotting functions.
 
-Term ``1D data'' means that data depend on single index (parameter) like curve in parametric form @{x(i),y(i),z(i)@}, i=1...n. There are 5 generally different types of data representations: simple line plot, line plot with filling under it, stairs plot, bar plot and vertical lines (@pxref{1D plotting}). Each type of plotting has similar interface. There are 3D version and two 2D versions. One of last requires single array. The parameters of line and marks (@pxref{Line styles}) are specified by the string argument. If the string parameter is @code{NULL} then solid line with color from palette is used (@pxref{Palette and colors}).
+Let start for plots for 1D data. Term ``1D data'' means that data depend on single index (parameter) like curve in parametric form @{x(i),y(i),z(i)@}, i=1...n. The textual argument allow you specify styles of line and marks (see @ref{Line styles}). If this parameter is @code{NULL} or empty then solid line with color from palette is used (see @ref{Palette and colors}).
 
-Below I shall show the features of 1D plotting on base of @code{Plot()} function (@pxref{Plot}). Let us start from sinus plot:
+Below I shall show the features of 1D plotting on base of @code{Plot()} function (see @ref{plot}). Let us start from sinus plot:
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        mglData y0(50);        y0.Modify("sin(pi*(2*x-1))");
-        gr->SubPlot(2,2,0);
-        gr->Plot(y0);          gr->Box();
+int sample(mglGraph *gr)
+{
+  mglData y0(50);      y0.Modify("sin(pi*(2*x-1))");
+  gr->SubPlot(2,2,0);
+  gr->Plot(y0);        gr->Box();
 @end verbatim
 Style of line is not specified in @code{Plot()} function. So MathGL uses the solid line with first color of palette (this is blue). Next subplot shows array @var{y1} with 2 rows:
 @verbatim
-        gr->SubPlot(2,2,1);
-        mglData y1(50,2);
-        y1.Modify("sin(pi*2*x-pi)");
-        y1.Modify("cos(pi*2*x-pi)/2",1);
-        gr->Plot(y1);          gr->Box();
+  gr->SubPlot(2,2,1);
+  mglData y1(50,2);
+  y1.Modify("sin(pi*2*x-pi)");
+  y1.Modify("cos(pi*2*x-pi)/2",1);
+  gr->Plot(y1);        gr->Box();
 @end verbatim
 As previously I did not specify the style of lines. As a result, MathGL again uses solid line with next colors in palette (there are green and red). Now let us plot a circle on the same subplot. The circle is parametric curve @math{x=cos(\pi t), y=sin(\pi t)}. I will set the color of the circle (dark yellow, @samp{Y}) and put marks @samp{+} at point position:
 @verbatim
-        mglData x(50);         x.Modify("cos(pi*2*x-pi)");
-        gr->Plot(x,y0,"Y+");
+  mglData x(50);       x.Modify("cos(pi*2*x-pi)");
+  gr->Plot(x,y0,"Y+");
 @end verbatim
 Note that solid line is used because I did not specify the type of line. The same picture can be achieved by @code{Plot()} and @code{SubData())} functions. Let us draw ellipse by orange dash line:
 @verbatim
-        gr->Plot(y1.SubData(-1,0),y1.SubData(-1,1),"q|");
+  gr->Plot(y1.SubData(-1,0),y1.SubData(-1,1),"q|");
 @end verbatim
 
 Drawing in 3D space is mostly the same. Let us draw spiral with default line style. Now its color is 4-th color from palette (this is cyan):
 @verbatim
-        gr->SubPlot(2,2,2);    gr->Rotate(60,40);
-        mglData z(50);         z.Modify("2*x-1");
-        gr->Plot(x,y0,z);      gr->Box();
+  gr->SubPlot(2,2,2);  gr->Rotate(60,40);
+  mglData z(50);       z.Modify("2*x-1");
+  gr->Plot(x,y0,z);    gr->Box();
 @end verbatim
 Functions @code{Plot()} and @code{SubData())} make 3D curve plot but for single array. Use it to put circle marks on the previous plot:
 @verbatim
-        mglData y2(10,3);      y2.Modify("cos(pi*(2*x-1+y))");
-        y2.Modify("2*x-1",2);
-        gr->Plot(y2.SubData(-1,0),y2.SubData(-1,1),y2.SubData(-1,2),"bo ");
+  mglData y2(10,3);    y2.Modify("cos(pi*(2*x-1+y))");
+  y2.Modify("2*x-1",2);
+  gr->Plot(y2.SubData(-1,0),y2.SubData(-1,1),y2.SubData(-1,2),"bo ");
 @end verbatim
 Note that line style is empty @samp{ } here. Usage of other 1D plotting functions looks similar:
 @verbatim
-        gr->SubPlot(2,2,3);    gr->Rotate(60,40);
-        gr->Bars(x,y0,z,"r");  gr->Box();
-        return 0;
-    }
+  gr->SubPlot(2,2,3);  gr->Rotate(60,40);
+  gr->Bars(x,y0,z,"r");        gr->Box();
+  return 0;
+}
 @end verbatim
 
-@float
-@image{../png/sample8, 7cm}
-@caption{Example of 1D data plot}
-@end float
-
-@c ------------------------------------------------------------------
-@node Plots for 2D data, Plots for 3D data, Plots for 1D data, Data plotting
-@subsection Plots for 2D data
-
-Surfaces @code{Surf()} and other 2D plots (@pxref{2D plotting}) are drown the same simpler as 1D one. The difference is that the string parameter specifies not by line style but by the color scheme of the plot (@pxref{Color scheme}). Here I draw attention on 4 most interesting color schemes. There is gray scheme where color is changed from black to white (string @samp{kw}) or from white to black (string @samp{wk}). Another scheme is useful for accentuation of negative (by blue color) and positive (by red color) regions on plot (string @samp{"BbwrR"}). Last one is the popular ``jet'' scheme (string @samp{"BbcyrR"}).
+Surfaces @code{Surf()} and other 2D plots (@pxref{2D plotting}) are drown the same simpler as 1D one. The difference is that the string parameter specifies not the line style but the color scheme of the plot (see @ref{Color scheme}). Here I draw attention on 4 most interesting color schemes. There is gray scheme where color is changed from black to white (string @samp{kw}) or from white to black (string @samp{wk}). Another scheme is useful for accentuation of negative (by blue color) and positive (by red color) regions on plot (string @samp{"BbwrR"}). Last one is the popular ``jet'' scheme (string @samp{"BbcyrR"}).
 
 Now I shall show the example of a surface drawing. At first let us switch lightning on
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->Light(true);       gr->Light(0,mglPoint(0,0,1));
+int sample(mglGraph *gr)
+{
+  gr->Light(true);     gr->Light(0,mglPoint(0,0,1));
 @end verbatim
 and draw the surface, considering coordinates x,y to be uniformly distributed in interval @var{Min}*@var{Max}
 @verbatim
-        mglData a0(50,40);
-        a0.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
-        gr->SubPlot(2,2,0);    gr->Rotate(60,40);
-        gr->Surf(a0);          gr->Box();
+  mglData a0(50,40);
+  a0.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
+  gr->SubPlot(2,2,0);  gr->Rotate(60,40);
+  gr->Surf(a0);                gr->Box();
 @end verbatim
 Color scheme was not specified. So previous color scheme is used. In this case it is default color scheme (``jet'') for the first plot. Next example is a sphere. The sphere is parametrically specified surface:
 @verbatim
-        mglData x(50,40),y(50,40),z(50,40);
-        x.Modify("0.8*sin(2*pi*x)*sin(pi*y)");
-        y.Modify("0.8*cos(2*pi*x)*sin(pi*y)");
-        z.Modify("0.8*cos(pi*y)");
-        gr->SubPlot(2,2,1);    gr->Rotate(60,40);
-        gr->Surf(x,y,z,"BbwrR");gr->Box();
+  mglData x(50,40),y(50,40),z(50,40);
+  x.Modify("0.8*sin(2*pi*x)*sin(pi*y)");
+  y.Modify("0.8*cos(2*pi*x)*sin(pi*y)");
+  z.Modify("0.8*cos(pi*y)");
+  gr->SubPlot(2,2,1);  gr->Rotate(60,40);
+  gr->Surf(x,y,z,"BbwrR");gr->Box();
 @end verbatim
 I set color scheme to @code{"BbwrR"} that corresponds to red top and blue bottom of the sphere.
 
 Surfaces will be plotted for each of slice of the data if @var{nz}>1. Next example draws surfaces for data arrays with @var{nz}=3:
 @verbatim
-        mglData a1(50,40,3);
-        a1.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
-        a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*sin(3*pi*(x*y))",1);
-        a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*cos(3*pi*(x*y))",2);
-        gr->SubPlot(2,2,2);    gr->Rotate(60,40);
-        gr->Alpha(true);
-        gr->Surf(a1);          gr->Box();
+  mglData a1(50,40,3);
+  a1.Modify("0.6*sin(2*pi*x)*sin(3*pi*y)+0.4*cos(3*pi*(x*y))");
+  a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*sin(3*pi*(x*y))",1);
+  a1.Modify("0.6*cos(2*pi*x)*cos(3*pi*y)+0.4*cos(3*pi*(x*y))",2);
+  gr->SubPlot(2,2,2);  gr->Rotate(60,40);
+  gr->Alpha(true);
+  gr->Surf(a1);                gr->Box();
 @end verbatim
 Note, that it may entail a confusion. However, if one will use density plot then the picture will look better:
 @verbatim
-        gr->SubPlot(2,2,3);    gr->Rotate(60,40);
-        gr->Dens(a1);          gr->Box();
-        return 0;
-    }
+  gr->SubPlot(2,2,3);  gr->Rotate(60,40);
+  gr->Dens(a1);                gr->Box();
+  return 0;
+}
 @end verbatim
-Note, that the previous color scheme is used in last plots because there are no direct specification of the one.
-
-@float
-@image{../png/sample9, 7cm}
-@caption{Example of surface plot for 2D data}
-@end float
 
 Drawing of other 2D plots is analogous. The only peculiarity is the usage of flag @samp{#}. By default this flag switches on the drawing of a grid on plot (@code{Grid()} or @code{Mesh()} for plots in plain or in volume). However, for isosurfaces (including surfaces of rotation @code{Axial()}) this flag switches the  face drawing off. Figure becomes wired. The following code gives example of flag @samp{#} using (compare with normal function drawing as in its description):
 @verbatim
-    int sample(mglGraph *gr, void *)
-    {
-        gr->Alpha(true);       gr->Light(true);        gr->Light(0,mglPoint(0,0,1));
-        mglData a(30,20);
-        a.Modify("0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))");
-
-        gr->SubPlot(2,2,0);    gr->Rotate(40,60);
-        gr->Surf(a,"BbcyrR#");         gr->Box();
-        gr->SubPlot(2,2,1);    gr->Rotate(40,60);
-        gr->Dens(a,"BbcyrR#");         gr->Box();
-        gr->SubPlot(2,2,2);    gr->Rotate(40,60);
-        gr->Cont(a,"BbcyrR#");         gr->Box();
-        gr->SubPlot(2,2,3);    gr->Rotate(40,60);
-        gr->Axial(a,"BbcyrR#");                gr->Box();
-        return 0;
-    }
-@end verbatim
+int sample(mglGraph *gr)
+{
+  gr->Alpha(true);     gr->Light(true);        gr->Light(0,mglPoint(0,0,1));
+  mglData a(30,20);
+  a.Modify("0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))");
 
-@float
-@image{../png/samplea, 7cm}
-@caption{Example of 2D data plot with color scheme contained @samp{#} symbol}
-@end float
+  gr->SubPlot(2,2,0);  gr->Rotate(40,60);
+  gr->Surf(a,"BbcyrR#");               gr->Box();
+  gr->SubPlot(2,2,1);  gr->Rotate(40,60);
+  gr->Dens(a,"BbcyrR#");               gr->Box();
+  gr->SubPlot(2,2,2);  gr->Rotate(40,60);
+  gr->Cont(a,"BbcyrR#");               gr->Box();
+  gr->SubPlot(2,2,3);  gr->Rotate(40,60);
+  gr->Axial(a,"BbcyrR#");              gr->Box();
+  return 0;
+}
+@end verbatim
 
 @c ------------------------------------------------------------------
-@node Plots for 3D data, Surface transparency, Plots for 2D data, Data plotting
-@subsection Plots for 3D data
-
-Drawing procedures for 3D plot looks similarly to 1D and 2D plots described above. There are 3 general types of 3D plots (@pxref{3D plotting}): (i) plots on slices or on projections, (ii) isosurfaces, (iii) cloud-like plots. Plots on slice are clear enough -- one specifies a slice (as its index or as coordinate value) and MathGL draws contour lines or density plot on slice plane. Isosurface gives more information. Isosurface is 3D analogue of the contour line @code{Cont()}. It shows the region where data array values exceed specified isosurface level. Plot becomes more informative if one adds transparency, lightning or sets color scheme depending on coordinates. Generalization of isosurface is the cloud-like plot. For this plot the darker color and less transparent regions correspond to higher values of data. Contrary, the regions with low values are transparent. For plotting of the phase of fields (or beams or pulses) one can use isosurface which transparency depends on the other data array (see function @code{Surf3A()}). As example of 3D data plots let us draw the Gaussian beam diffraction in space. Beam propagates along @var{x} axis:
-@verbatim
-    int sample(mglGraph *gr, void *)
+@node 1D samples, 2D samples, Data plotting, Examples
+@section 1D samples
+
+This section is devoted to visualization of 1D data arrays. 1D means the data which depend on single index (parameter) like curve in parametric form @{x(i),y(i),z(i)@}, i=1...n. Most of samples will use the same data for plotting. So, I put its initialization in separate function
+@verbatim
+void mgls_prepare1d(mglData *y, mglData *y1=0, mglData *y2=0, mglData *x1=0, mglData *x2=0)
+{
+  register long i,n=50;
+  if(y) y->Create(n,3);
+  if(x1)  x1->Create(n);    if(x2)  x2->Create(n);
+  if(y1)  y1->Create(n);    if(y2)  y2->Create(n);
+  float xx;
+  for(i=0;i<n;i++)
+  {
+    xx = i/(n-1.);
+    if(y)
     {
-        gr->Alpha(true);    gr->Light(true);
-        gr->Light(0,mglPoint(0,0,1));
-        mglData a(30,30,30),b(30,30,30);
-        a.Modify("exp(-16*((z-0.5)^2+(y-0.5)^2)/(1+4*x^2))");
-        b.Modify("16*((z-0.5)^2+(y-0.5)^2)*(x)/(1+4*x^2)");
-        gr->CAxis(0,1);
-
-        gr->SubPlot(2,2,0); gr->Rotate(40,60);
-        gr->Surf3(a,"wgk"); gr->Box();
-        gr->SubPlot(2,2,1); gr->Rotate(40,60);
-        gr->DensA(a);       gr->Box();  gr->Axis();
-        gr->SubPlot(2,2,2); gr->Rotate(40,60);
-        gr->CloudQ(a);      gr->Box();
-        gr->SubPlot(2,2,3); gr->Rotate(40,60);
-        gr->Surf3A(b,a,"q");gr->Box();
-        return 0;
+      y->a[i] = 0.7*sin(2*M_PI*xx) + 0.5*cos(3*M_PI*xx) + 0.2*sin(M_PI*xx);
+      y->a[i+n] = sin(2*M_PI*xx);
+      y->a[i+2*n] = cos(2*M_PI*xx);
     }
+    if(y1)  y1->a[i] = 0.5+0.3*cos(2*M_PI*xx);
+    if(y2)  y2->a[i] = 0.3*sin(2*M_PI*xx);
+    if(x1)  x1->a[i] = xx*2-1;
+    if(x2)  x2->a[i] = 0.05+0.03*cos(2*M_PI*xx);
+  }
+}
+@end verbatim
+or using C functions
+@verbatim
+void mgls_prepare1d(HMDT y, HMDT y1=0, HMDT y2=0, HMDT x1=0, HMDT x2=0)
+{
+  register long i,n=50;
+  if(y)   mgl_data_create(y,n,3,1);
+  if(x1)  mgl_data_create(x1,n,1,1);
+  if(x2)  mgl_data_create(x2,n,1,1);
+  if(y1)  mgl_data_create(y1,n,1,1);
+  if(y2)  mgl_data_create(y2,n,1,1);
+  float xx;
+  for(i=0;i<n;i++)
+  {
+    xx = i/(n-1.);
+    if(y)
+    {
+      mgl_data_set_value(y, 0.7*sin(2*M_PI*xx) + 0.5*cos(3*M_PI*xx) + 0.2*sin(M_PI*xx), i,0,0);
+      mgl_data_set_value(y, sin(2*M_PI*xx), i,1,0);
+      mgl_data_set_value(y, cos(2*M_PI*xx), i,2,0);
+    }
+    if(y1)  mgl_data_set_value(y1, 0.5+0.3*cos(2*M_PI*xx), i,0,0);
+    if(y2)  mgl_data_set_value(y2, 0.3*sin(2*M_PI*xx), i,0,0);
+    if(x1)  mgl_data_set_value(x1, xx*2-1, i,0,0);
+    if(x2)  mgl_data_set_value(x2, 0.05+0.03*cos(2*M_PI*xx), i,0,0);
+  }
+}
 @end verbatim
 
-@float
-@image{../png/sampleb, 7cm}
-@caption{Example of Gaussian beam diffraction (3D data)}
-@end float
+@menu
+* Plot sample::
+* Radar sample::
+* Step sample::
+* Tens sample::
+* Area sample::
+* Region sample::
+* Stem sample::
+* Bars sample::
+* Barh sample::
+* Cones sample::
+* Chart sample::
+* BoxPlot sample::
+* Candle sample::
+* Error sample::
+* Mark sample::
+* TextMark sample::
+* Label sample::
+* Tube sample::
+* Tape sample::
+* Torus sample::
+@end menu
 
 
 @c ------------------------------------------------------------------
-@node Surface transparency, , Plots for 3D data, Data plotting
-@subsection Surface transparency
+@node Plot sample, Radar sample, , 1D samples
+@subsection Plot sample
 
-MathGL library has advanced features for setting and handling the surface transparency. The simplest way to add transparency is the using of function @code{Alpha()}. As a result, all further surfaces (and isosurfaces, density plots and so on) become transparent. However, their  look can be additionally improved.
+@code{Plot} is most standard way to visualize 1D data array. By default, @code{Plot} use colors from palette. However, you can specify manual color/palette, and even set to use new color for each points by using @samp{!} style. Another feature is @samp{ } style which draw only markers without line between points. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y); gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0,"");  gr->Title("Plot plot (default)");
+  gr->Box();  gr->Plot(y);
 
-First, the selected surface will be non-transparent if one sets the flag @code{Transparent} before the surface drawing and sets it off after the drawing.
+  gr->SubPlot(2,2,2,"");  gr->Title("'!' style; 'rgb' palette");
+  gr->Box();  gr->Plot(y,"o!rgb");
 
-Second, the value of transparency can be different from surface to surface. To do it just change the value of @code{AlphaDef} before the drawing of the selected surface. If its value is close to 0 then the surface becomes more and more transparent. Contrary, if its value is close to 1 then the surface becomes practically non-transparent. This is some analogue of @code{Transparent=true}.
+  gr->SubPlot(2,2,3,"");  gr->Title("just markers");
+  gr->Box();  gr->Plot(y," +");
 
-Third feature is the changing of the way how the light goes through overlapped surfaces. The variable @code{TranspType} defines it. By default the usual transparency is used (@code{TranspType=0}) -- surfaces below is less visible than the upper ones. A ``glass-like'' transparency (@code{TranspType=1}) has a different look when the surface just decreases the background light (the surfaces are commutable in this case).
+  gr->SubPlot(2,2,1); gr->Title("3d variant");
+  gr->Rotate(50,60);  gr->Box();
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+  gr->Plot(xc,yc,z,"rs");
+  return 0;
+}
+@end verbatim
 
-A ``neon-like'' transparency (@code{TranspType=2}) has more interesting look. In this case a surface is the light source (like a lamp on the dark background) and just adds some intensity to the color. At this, the library sets automatically the black color for the background and changes the default line color to white.
+@fig{png/plot, Example of Plot()}
 
-As example I shall show the variant of plot from @ref{Plots for 2D data} (grid drawing is disabled) for different types of transparency.
-@float
-@image{../png/type0, 7cm}
-@caption{Example of @code{TranspType=0}.}
-@end float
-@float
-@image{../png/type1, 7cm}
-@caption{Example of @code{TranspType=1}.}
-@end float
-@float
-@image{../png/type2, 7cm}
-@caption{Example of @code{TranspType=2}.}
-@end float
 
 @c ------------------------------------------------------------------
-@node C/Fortran interface, MathGL and PyQt, Data plotting, Examples
-@section C/Fortran interface
-
-The usage of pure C or Fortran or any similar interfaces (@pxref{C interface}) is practically identical to classes usage. But there are some differences. C functions must have argument HMGL (for graphics) and/or HMDT (for data arrays) which specifies the object for drawing or manipulating (changing). Fortran users may regard these variables as integer. So, firstly the user has to create this object by function mgl_create_*() and has to delete it after the using by function mgl_delete_*().
+@node Radar sample, Step sample, Plot sample, 1D samples
+@subsection Radar sample
+
+@code{Radar} plot is variant of @code{Plot} one, which make plot in polar coordinates and draw radial rays in point directions. If you just need a plot in polar coordinates then I recommend to use @ref{Curvilinear coordinates} or @code{Plot} in parabolic form with @code{x=r*cos(fi); y=r*sin(fi);}. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData yr(10,3); yr.Modify("0.4*sin(pi*(2*x+y))+0.1*rnd");
+  gr->SubPlot(1,1,0,"");  gr->Title("Radar plot (with grid, '\\#')");
+  gr->Radar(yr,"#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/radar, Example of Radar()}
+
+@c ------------------------------------------------------------------
+@node Step sample, Tens sample, Radar sample, 1D samples
+@subsection Step sample
+
+@code{Step} plot data as stairs. It have the same options as @code{Plot}. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y); gr->SetOrigin(0,0,0);
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+
+  gr->SubPlot(2,2,0,"");  gr->Title("Step plot (default)");
+  gr->Box();  gr->Step(y);
+
+  gr->SubPlot(2,2,1); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Step(xc,yc,z,"r");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'!' style");
+  gr->Box();  gr->Step(y,"s!rgb");
+  return 0;
+}
+@end verbatim
+
+@fig{png/step, Example of Step()}
+
+@c ------------------------------------------------------------------
+@node Tens sample, Area sample, Step sample, 1D samples
+@subsection Tens sample
+
+@code{Tens} is variant of @code{Plot} with smooth coloring along the curves. At this, color is determined as for surfaces (see @ref{Color scheme}). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y); gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0,"");  gr->Title("Tens plot (default)");
+  gr->Box();  gr->Tens(y.SubData(-1,0), y.SubData(-1,1));
+
+  gr->SubPlot(2,2,2,"");  gr->Title("' ' style");
+  gr->Box();  gr->Tens(y.SubData(-1,0), y.SubData(-1,1),"o ");
+
+  gr->SubPlot(2,2,1); gr->Title("3d variant");  gr->Rotate(50,60);  gr->Box();
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+  gr->Tens(xc,yc,z,z,"s");
+  return 0;
+}
+@end verbatim
+
+@fig{png/tens, Example of Tens()}
+
+@c ------------------------------------------------------------------
+@node Area sample, Region sample, Tens sample, 1D samples
+@subsection Area sample
+
+@code{Area} fill the area between curve and axis plane. It support gradient filling if 2 colors per curve is specified. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y); gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0,"");  gr->Title("Area plot (default)");
+  gr->Box();  gr->Area(y);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("2 colors");
+  gr->Box();  gr->Area(y,"cbgGyr");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'!' style");
+  gr->Box();  gr->Area(y,"!");
+
+  gr->SubPlot(2,2,3); gr->Title("3d variant");
+  gr->Rotate(50,60);  gr->Box();
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+  gr->Area(xc,yc,z,"r");
+  return 0;
+}
+@end verbatim
+
+@fig{png/area, Example of Area()}
+
+@c ------------------------------------------------------------------
+@node Region sample, Stem sample, Area sample, 1D samples
+@subsection Region sample
+
+@code{Region} fill the area between 2 curves. It support gradient filling if 2 colors per curve is specified. Also it can fill only the region y1<y<y2 if style @samp{i} is used. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y);
+  mglData y1 = y.SubData(-1,1), y2 = y.SubData(-1,2); gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0,"");  gr->Title("Region plot (default)");
+  gr->Box();  gr->Region(y1,y2);  gr->Plot(y1,"k2");  gr->Plot(y2,"k2");
+
+  gr->SubPlot(2,2,1,"");  gr->Title("2 colors");
+  gr->Box();  gr->Region(y1,y2,"yr"); gr->Plot(y1,"k2");  gr->Plot(y2,"k2");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'!' style");
+  gr->Box();  gr->Region(y1,y2,"!");  gr->Plot(y1,"k2");  gr->Plot(y2,"k2");
+
+  gr->SubPlot(2,2,3,"");  gr->Title("'i' style");
+  gr->Box();  gr->Region(y1,y2,"ir"); gr->Plot(y1,"k2");  gr->Plot(y2,"k2");
+  return 0;
+}
+@end verbatim
+
+@fig{png/region, Example of Region()}
+
+@c ------------------------------------------------------------------
+@node Stem sample, Bars sample, Region sample, 1D samples
+@subsection Stem sample
+
+@code{Stem} draw vertical bars. It is most attractive if markers are drawn too. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y); gr->SetOrigin(0,0,0);
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+  gr->SubPlot(2,2,0,"");  gr->Title("Stem plot (default)");
+  gr->Box();  gr->Stem(y);
+
+  gr->SubPlot(2,2,1); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Stem(xc,yc,z,"rx");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'!' style");
+  gr->Box();  gr->Stem(y,"o!rgb");
+  return 0;
+}
+@end verbatim
+
+@fig{png/stem, Example of Stem()}
+
+@c ------------------------------------------------------------------
+@node Bars sample, Barh sample, Stem sample, 1D samples
+@subsection Bars sample
+
+@code{Bars} draw vertical bars. It have a lot of options: bar-above-bar (@samp{a} style), fall like (@samp{f} style), 2 colors for positive and negative values, wired bars (@samp{#} style), 3D variant. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData ys(10,3); ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
+  gr->SetOrigin(0,0,0);
+  gr->SubPlot(3,2,0,"");  gr->Title("Bars plot (default)");
+  gr->Box();  gr->Bars(ys);
+
+  gr->SubPlot(3,2,1,"");  gr->Title("2 colors");
+  gr->Box();  gr->Bars(ys,"cbgGyr");
+
+  gr->SubPlot(3,2,4,"");  gr->Title("'\\#' style");
+  gr->Box();  gr->Bars(ys,"#");
+
+  gr->SubPlot(3,2,5); gr->Title("3d variant");
+  gr->Rotate(50,60);  gr->Box();
+  mglData yc(30), xc(30), z(30);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+  gr->Bars(xc,yc,z,"r");
+
+  gr->SetRanges(-1,1,-3,3);
+  gr->SubPlot(3,2,2,"");  gr->Title("'a' style");
+  gr->Box();  gr->Bars(ys,"a");
+
+  gr->SubPlot(3,2,3,"");  gr->Title("'f' style");
+  gr->Box();  gr->Bars(ys,"f");
+  return 0;
+}
+@end verbatim
+
+@fig{png/bars, Example of Bars()}
+
+@c ------------------------------------------------------------------
+@node Barh sample, Cones sample, Bars sample, 1D samples
+@subsection Barh sample
+
+@code{Barh} is the similar to @code{Bars} but draw horizontal bars. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData ys(10,3); ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
+  gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0,"");  gr->Title("Barh plot (default)");
+  gr->Box();  gr->Barh(ys);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("2 colors");
+  gr->Box();  gr->Barh(ys,"cbgGyr");
+
+  gr->SetRanges(-3,3,-1,1);
+  gr->SubPlot(2,2,2,"");  gr->Title("'a' style");
+  gr->Box();  gr->Barh(ys,"a");
+
+  gr->SubPlot(2,2,3,"");  gr->Title("'f' style");
+  gr->Box();  gr->Barh(ys,"f");
+  return 0;
+}
+@end verbatim
+
+@fig{png/barh, Example of Barh()}
+
+@c ------------------------------------------------------------------
+@node Cones sample, Chart sample, Bars sample, 1D samples
+@subsection Cones sample
+
+@code{Cones} is similar to @code{Bars} but draw cones. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData ys(10,3);   ys.Modify("0.8*sin(pi*(2*x+y/2))+0.2*rnd");
+  gr->Light(true);    gr->SetOrigin(0,0,0);
+  gr->SubPlot(2,2,0); gr->Title("Cones plot");
+  gr->Rotate(50,60);  gr->Box();  gr->Cones(ys);
+
+  gr->SubPlot(2,2,1); gr->Title("2 colors");
+  gr->Rotate(50,60);  gr->Box();  gr->Cones(ys,"cbgGyr");
+
+  gr->SubPlot(2,2,2); gr->Title("'#' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Cones(ys,"#");
+
+  gr->SubPlot(2,2,3); gr->Title("'a' style");
+  gr->SetRange('z',-2,2); // increase range since summation can exceed [-1,1]
+  gr->Rotate(50,60);  gr->Box();  gr->Cones(ys,"a");
+  return 0;
+}
+@end verbatim
+
+@fig{png/cones, Example of Cones()}
+
+@c ------------------------------------------------------------------
+@node Chart sample, BoxPlot sample, Cones sample, 1D samples
+@subsection Chart sample
+
+@code{Chart} draw colored boxes with width proportional to data values. Use @samp{ } for empty box. Plot looks most attractive in polar coordinates -- well known pie chart. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData ch(7,2);  for(int i=0;i<7*2;i++)  ch.a[i]=mgl_rnd()+0.1;
+  gr->SubPlot(2,2,0); gr->Title("Chart plot (default)");
+  gr->Light(true);  gr->Rotate(50,60);  gr->Box();  gr->Chart(ch);
+
+  gr->SubPlot(2,2,1); gr->Title("'\\#' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Chart(ch,"#");
+
+  gr->SubPlot(2,2,2); gr->Title("Pie chart; ' ' color");
+  gr->SetFunc("(y+1)/2*cos(pi*x)","(y+1)/2*sin(pi*x)","");
+  gr->Rotate(50,60);  gr->Box();  gr->Chart(ch,"bgr cmy#");
+
+  gr->SubPlot(2,2,3); gr->Title("Ring chart; ' ' color");
+  gr->SetFunc("(y+2)/3*cos(pi*x)","(y+2)/3*sin(pi*x)","");
+  gr->Rotate(50,60);  gr->Box();  gr->Chart(ch,"bgr cmy#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/chart, Example of Chart()}
+
+@c ------------------------------------------------------------------
+@node BoxPlot sample, Candle sample, Chart sample, 1D samples
+@subsection BoxPlot sample
+
+@code{BoxPlot} draw box-and-whisker diagram. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a(10,7);  a.Modify("(2*rnd-1)^3/2");
+  gr->SubPlot(1,1,0,"");  gr->Title("Boxplot plot");
+  gr->Box();  gr->BoxPlot(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/boxplot, Example of BoxPlot()}
+
+@c ------------------------------------------------------------------
+@node Candle sample, Error sample, BoxPlot sample, 1D samples
+@subsection Candle sample
+
+@code{Candle} draw candlestick chart. This is a combination of a line-chart and a bar-chart, in that each bar represents the range of price movement over a given time interval. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y(30);  gr->Fill(y,"sin(pi*x/2)^2");
+  mglData y1(30); gr->Fill(y1,"v/2",y);
+  mglData y2(30); gr->Fill(y2,"(1+v)/2",y);
+  gr->SubPlot(1,1,0,"");  gr->Title("Candle plot (default)");
+  gr->SetRange('y',0,1);  gr->Box();  gr->Candle(y,y1,y2);
+  return 0;
+}
+@end verbatim
+
+@fig{png/candle, Example of Candle()}
+
+@c ------------------------------------------------------------------
+@node Error sample, Mark sample, Candle sample, 1D samples
+@subsection Error sample
+
+@code{Error} draw error boxes around the points. You can draw default boxes or semi-transparent symbol (like marker, see @ref{Line styles}). Also you can set individual color for each box. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y);
+  mglData x0(10), y0(10), ex0(10), ey0(10);
+  float x;
+  for(int i=0;i<10;i++)
+  {
+    x = i/9.;
+    x0.a[i] = 2*x-1 + 0.1*mgl_rnd()-0.05;
+    y0.a[i] = 0.7*sin(2*M_PI*x)+0.5*cos(3*M_PI*x)+0.2*sin(M_PI*x)+0.2*mgl_rnd()-0.1;
+    ey0.a[i]=0.2; ex0.a[i]=0.1;
+  }
+
+  gr->SubPlot(2,2,0,"");  gr->Title("Error plot (default)");
+  gr->Box();  gr->Plot(y.SubData(-1,0));  gr->Error(x0,y0,ex0,ey0,"ko");
+
+  gr->SubPlot(2,2,1,"");  gr->Title("'!' style; no e_x");
+  gr->Box();  gr->Plot(y.SubData(-1,0));  gr->Error(x0,y0,ey0,"o!rgb");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'\\@' style");
+  gr->Box();  gr->Plot(y.SubData(-1,0));  gr->Error(x0,y0,ex0,ey0,"@","alpha 0.5");
+
+  gr->SubPlot(2,2,3); gr->Title("3d variant");  gr->Rotate(50,60);
+  for(int i=0;i<10;i++)
+    gr->Error(mglPoint(2*mgl_rnd()-1,2*mgl_rnd()-1,2*mgl_rnd()-1),
+              mglPoint(0.2,0.2,0.2),"bo");
+  gr->Axis();
+  return 0;
+}
+@end verbatim
+
+@fig{png/error, Example of Error()}
+
+@c ------------------------------------------------------------------
+@node Mark sample, TextMark sample, Error sample, 1D samples
+@subsection Mark sample
+
+@code{Mark} draw markers at points. It is mostly the same as @code{Plot} but marker size can be variable. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y,y1; mgls_prepare1d(&y,&y1);
+  gr->SubPlot(1,1,0,"");  gr->Title("Mark plot (default)");
+  gr->Box();  gr->Mark(y,y1,"s");
+  return 0;
+}
+@end verbatim
+
+@fig{png/mark, Example of Mark()}
+
+@c ------------------------------------------------------------------
+@node TextMark sample, Label sample, Mark sample, 1D samples
+@subsection TextMark sample
+
+@code{TextMark} like @code{Mark} but draw text instead of markers. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y,y1; mgls_prepare1d(&y,&y1);
+  gr->SubPlot(1,1,0,"");  gr->Title("TextMark plot (default)");
+  gr->Box();  gr->TextMark(y,y1,"\\gamma","r");
+  return 0;
+}
+@end verbatim
+
+@fig{png/textmark, Example of TextMark()}
+
+@c ------------------------------------------------------------------
+@node Label sample, Tube sample, TextMark sample, 1D samples
+@subsection Label sample
+
+@code{Label} print text at data points. The string may contain @samp{%x}, @samp{%y}, @samp{%z} for x-, y-, z-coordinates of points, @samp{%n} for point index. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData ys(10); ys.Modify("0.8*sin(pi*2*x)+0.2*rnd");
+  gr->SubPlot(1,1,0,"");  gr->Title("Label plot");
+  gr->Box();  gr->Plot(ys," *");  gr->Label(ys,"y=%y");
+  return 0;
+}
+@end verbatim
+
+@fig{png/label, Example of Label()}
+
+
+@c ------------------------------------------------------------------
+@node Tube sample, Tape sample, Label sample, 1D samples
+@subsection Tube sample
+
+@code{Tube} draw tube with variable radius. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y,y1,y2;  mgls_prepare1d(&y,&y1,&y2); y1/=20;
+  gr->SubPlot(2,2,0,"");  gr->Title("Tube plot (default)");
+  gr->Light(true);  gr->Box();  gr->Tube(y,0.05);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("variable radius");
+  gr->Box();  gr->Tube(y,y1);
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'\\#' style");
+  gr->Box();  gr->Tube(y,0.05,"#");
+  mglData yc(50), xc(50), z(50);  z.Modify("2*x-1");
+  yc.Modify("sin(pi*(2*x-1))"); xc.Modify("cos(pi*2*x-pi)");
+
+  gr->SubPlot(2,2,3); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Tube(xc,yc,z,y2,"r");
+  return 0;
+}
+@end verbatim
+
+@fig{png/tube, Example of Tube()}
+
+
+@c ------------------------------------------------------------------
+@node Tape sample, Torus sample, Tube sample, 1D samples
+@subsection Tape sample
+
+@code{Tape} draw tapes which rotate around the curve as normal and binormal. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y;  mgls_prepare1d(&y);
+  mglData xc(50), yc(50), z(50);
+  yc.Modify("sin(pi*(2*x-1))");
+  xc.Modify("cos(pi*2*x-pi)");  z.Fill(-1,1);
+  gr->SubPlot(2,2,0,"");  gr->Title("Tape plot (default)");
+  gr->Box();  gr->Tape(y);  gr->Plot(y,"k");
+
+  gr->SubPlot(2,2,1); gr->Title("3d variant, 2 colors");
+  gr->Rotate(50,60);  gr->Light(true);
+  gr->Box();  gr->Plot(xc,yc,z,"k");  gr->Tape(xc,yc,z,"rg");
+
+  gr->SubPlot(2,2,2); gr->Title("3d variant, x only");  gr->Rotate(50,60);
+  gr->Box();  gr->Plot(xc,yc,z,"k");
+  gr->Tape(xc,yc,z,"xr"); gr->Tape(xc,yc,z,"xr#");
+
+  gr->SubPlot(2,2,3); gr->Title("3d variant, z only");  gr->Rotate(50,60);
+  gr->Box();  gr->Plot(xc,yc,z,"k");
+  gr->Tape(xc,yc,z,"zg"); gr->Tape(xc,yc,z,"zg#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/tape, Example of Tape()}
+
+
+@c ------------------------------------------------------------------
+@node Torus sample, , Tape sample, 1D samples
+@subsection Torus sample
+
+@code{Torus} draw surface of the curve rotation. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData y1,y2;  mgls_prepare1d(0,&y1,&y2);
+  gr->SubPlot(2,2,0); gr->Title("Torus plot (default)");
+  gr->Light(true);  gr->Rotate(50,60);  gr->Box();  gr->Torus(y1,y2);
+  if(mini)  return;
+
+  gr->SubPlot(2,2,1); gr->Title("'x' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Torus(y1,y2,"x");
+
+  gr->SubPlot(2,2,2); gr->Title("'z' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Torus(y1,y2,"z");
+
+  gr->SubPlot(2,2,3); gr->Title("'\\#' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Torus(y1,y2,"#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/torus, Example of Torus()}
+
+
+@c ------------------------------------------------------------------
+@node 2D samples, 3D samples, 1D samples, Examples
+@section 2D samples
+
+This section is devoted to visualization of 2D data arrays. 2D means the data which depend on 2 indexes (parameters) like matrix z(i,j)=z(x(i),y(j)), i=1...n, j=1...m or in parametric form @{x(i,j),y(i,j),z(i,j)@}. Most of samples will use the same data for plotting. So, I put its initialization in separate function
+@verbatim
+void mgls_prepare2d(mglData *a, mglData *b=0, mglData *v=0)
+{
+  register long i,j,n=50,m=40,i0;
+  if(a) a->Create(n,m);   if(b) b->Create(n,m);
+  if(v) { v->Create(9); v->Fill(-1,1);  }
+  float x,y;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)
+  {
+    x = i/(n-1.); y = j/(m-1.); i0 = i+n*j;
+    if(a) a->a[i0] = 0.6*sin(2*M_PI*x)*sin(3*M_PI*y)+0.4*cos(3*M_PI*x*y);
+    if(b) b->a[i0] = 0.6*cos(2*M_PI*x)*cos(3*M_PI*y)+0.4*cos(3*M_PI*x*y);
+  }
+}
+@end verbatim
+or using C functions
+@verbatim
+void mgls_prepare2d(HMDT a, HMDT b=0, HMDT v=0)
+{
+  register long i,j,n=50,m=40,i0;
+  if(a) mgl_data_create(a,n,m,1);
+  if(b) mgl_data_create(b,n,m,1);
+  if(v) { mgl_data_create(v,9,1,1); mgl_data_fill(v,-1,1,'x');  }
+  float x,y;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)
+  {
+    x = i/(n-1.); y = j/(m-1.); i0 = i+n*j;
+    if(a) mgl_data_set_value(a, 0.6*sin(2*M_PI*x)*sin(3*M_PI*y)+0.4*cos(3*M_PI*x*y), i,j,0);
+    if(b) mgl_data_set_value(b, 0.6*cos(2*M_PI*x)*cos(3*M_PI*y)+0.4*cos(3*M_PI*x*y), i,j,0);
+  }
+}
+@end verbatim
+
+@menu
+* Surf sample::
+* SurfC sample::
+* SurfA sample::
+* Mesh sample::
+* Fall sample::
+* Belt sample::
+* Boxs sample::
+* Tile sample::
+* TileS sample::
+* Dens sample::
+* Cont sample::
+* ContF sample::
+* ContD sample::
+* ContV sample::
+* Axial sample::
+* Grad sample::
+@end menu
+
+@c ------------------------------------------------------------------
+@node Surf sample, SurfC sample, , 2D samples
+@subsection Surf sample
+
+@code{Surf} is most standard way to visualize 2D data array. @code{Surf} use color scheme for coloring (see @ref{Color scheme}). You can use @samp{#} style for drawing black meshes on the surface. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->SubPlot(2,2,0); gr->Title("Surf plot (default)");
+  gr->Light(true);  gr->Rotate(50,60);  gr->Box();  gr->Surf(a);
+
+  gr->SubPlot(2,2,1); gr->Title("'\\#' style; meshnum 10");
+  gr->Rotate(50,60);  gr->Box();  gr->Surf(a,"#","meshnum 10");
+
+  gr->SubPlot(2,2,2); gr->Title("'|' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Surf(a,"|");
+
+  gr->SubPlot(2,2,3); gr->Title("parametric form");
+  mglData x(50,40),y(50,40),z(50,40);
+  gr->Fill(x,"0.8*sin(pi*x)*sin(pi*(y+1)/2)");
+  gr->Fill(y,"0.8*cos(pi*x)*sin(pi*(y+1)/2)");
+  gr->Fill(z,"0.8*cos(pi*(y+1)/2)");
+  gr->Rotate(50,60);  gr->Box();  gr->Surf(x,y,z,"BbwrR");
+  return 0;
+}
+@end verbatim
+
+@fig{png/surf, Example of Surf()}
+
+@c ------------------------------------------------------------------
+@node SurfC sample, SurfA sample, Surf sample, 2D samples
+@subsection SurfC sample
+
+@code{SurfC} is similar to @code{Surf} but its coloring is determined by another data. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2d(&a,&b);
+  gr->Title("SurfC plot");  gr->Rotate(50,60);
+  gr->Light(true);  gr->Box();  gr->SurfC(a,b);
+  return 0;
+}
+@end verbatim
+
+@fig{png/surfc, Example of SurfC()}
+
+@c ------------------------------------------------------------------
+@node SurfA sample, Mesh sample, SurfC sample, 2D samples
+@subsection SurfA sample
+
+@code{SurfA} is similar to @code{Surf} but its transparency is determined by another data. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2d(&a,&b);
+  gr->Title("SurfA plot");  gr->Rotate(50,60);
+  gr->Alpha(true);  gr->Light(true);
+  gr->Box();  gr->SurfA(a,b);
+  return 0;
+}
+@end verbatim
+
+@fig{png/surfa, Example of SurfA()}
+
+
+@c ------------------------------------------------------------------
+@node Mesh sample, Fall sample, SurfA sample, 2D samples
+@subsection Mesh sample
+
+@code{Mesh} draw wired surface. You can use @code{SetMeshNum} for changing number of lines to be drawn. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Mesh plot"); gr->Rotate(50,60);
+  gr->Box();  gr->Mesh(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/mesh, Example of Mesh()}
+
+@c ------------------------------------------------------------------
+@node Fall sample, Belt sample, Mesh sample, 2D samples
+@subsection Fall sample
+
+@code{Fall} draw waterfall surface. You can use @code{SetMeshNum} for changing number of lines to be drawn. Also you can use @samp{x} style for drawing lines in other direction. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Fall plot"); gr->Rotate(50,60);
+  gr->Box();  gr->Fall(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/fall, Example of Fall()}
+
+@c ------------------------------------------------------------------
+@node Belt sample, Boxs sample, Fall sample, 2D samples
+@subsection Belt sample
+
+@code{Belt} draw surface by belts. You can use @samp{x} style for drawing lines in other direction. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Belt plot"); gr->Rotate(50,60);
+  gr->Box();  gr->Belt(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/belt, Example of Belt()}
+
+@c ------------------------------------------------------------------
+@node Boxs sample, Tile sample, Fall sample, 2D samples
+@subsection Boxs sample
+
+@code{Boxs} draw surface by boxes. You can use @samp{#} for drawing wire plot. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->SetOrigin(0,0,0); gr->Light(true);
+  gr->SubPlot(2,2,0);  gr->Title("Boxs plot (default)");
+  gr->Rotate(40,60);  gr->Box();  gr->Boxs(a);
+
+  gr->SubPlot(2,2,1); gr->Title("'\\@' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Boxs(a,"@");
+
+  gr->SubPlot(2,2,2); gr->Title("'\\#' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Boxs(a,"#");
+
+  gr->SubPlot(2,2,3); gr->Title("compare with Tile");
+  gr->Rotate(50,60);  gr->Box();  gr->Tile(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/boxs, Example of Boxs()}
+
+@c ------------------------------------------------------------------
+@node Tile sample, TileS sample, Boxs sample, 2D samples
+@subsection Tile sample
+
+@code{Tile} draw surface by tiles. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Tile plot");
+  gr->Rotate(40,60);  gr->Box();  gr->Tile(a);
+  return 0;
+}
+@end verbatim
+
+@fig{png/tile, Example of Tile()}
+
+@c ------------------------------------------------------------------
+@node TileS sample, Dens sample, Tile sample, 2D samples
+@subsection TileS sample
+
+@code{TileS} is similar to @code{Tile} but tile sizes is determined by another data. This allows one to simulate transparency of the plot. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2d(&a,&b);
+  gr->SubPlot(1,1,0,""); gr->Title("TileS plot");
+  gr->Box();  gr->TileS(a,b);
+  return 0;
+}
+@end verbatim
+
+@fig{png/tiles, Example of TileS()}
+
+
+@c ------------------------------------------------------------------
+@node Dens sample, Cont sample, TileS sample, 2D samples
+@subsection Dens sample
+
+@code{Dens} draw density plot for surface. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,a1(30,40,3);  mgls_prepare2d(&a);
+  gr->Fill(a1,"0.6*sin(2*pi*x+pi*(z+1)/2)*sin(3*pi*y+pi*z) + 0.4*cos(3*pi*(x*y)+pi*(z+1)^2/2)");
+  gr->SubPlot(2,2,0,""); gr->Title("Dens plot (default)");
+  gr->Box();  gr->Dens(a);
+
+  gr->SubPlot(2,2,1); gr->Title("3d variant");
+  gr->Rotate(50,60);  gr->Box();  gr->Dens(a);
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'\\#' style; meshnum 10");
+  gr->Box();  gr->Dens(a,"#","meshnum 10");
+
+  gr->SubPlot(2,2,3); gr->Title("several slices");
+  gr->Rotate(50,60);    gr->Box();  gr->Dens(a1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/dens, Example of Dens()}
+
+@c ------------------------------------------------------------------
+@node Cont sample, ContF sample, Dens sample, 2D samples
+@subsection Cont sample
+
+@code{Cont} draw contour lines for surface. You can select automatic (default) or manual levels for contours, print contour labels, draw it on the surface (default) or at plane (as @code{Dens}). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,v(5); mgls_prepare2d(&a); v.a[0]=-0.5;  v.a[1]=-0.15; v.a[2]=0; v.a[3]=0.15;  v.a[4]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("Cont plot (default)");
+  gr->Rotate(50,60);  gr->Box();  gr->Cont(a);
+
+  gr->SubPlot(2,2,1); gr->Title("manual levels");
+  gr->Rotate(50,60);  gr->Box();  gr->Cont(v,a);
+
+  gr->SubPlot(2,2,2); gr->Title("'\\_' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Cont(a,"_");
+
+  gr->SubPlot(2,2,3,"");  gr->Title("'t' style");
+  gr->Box();  gr->Cont(a,"t");
+  return 0;
+}
+@end verbatim
+
+@fig{png/cont, Example of Cont()}
+
+@c ------------------------------------------------------------------
+@node ContF sample, ContD sample, Cont sample, 2D samples
+@subsection ContF sample
+
+@code{ContF} draw filled contours.  You can select automatic (default) or manual levels for contours. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,v(5),a1(30,40,3); mgls_prepare2d(&a); v.a[0]=-0.5;
+  v.a[1]=-0.15; v.a[2]=0; v.a[3]=0.15;  v.a[4]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("ContF plot (default)");
+  gr->Rotate(50,60);  gr->Box();  gr->ContF(a);
+
+  gr->SubPlot(2,2,1); gr->Title("manual levels");
+  gr->Rotate(50,60);  gr->Box();  gr->ContF(v,a);
+
+  gr->SubPlot(2,2,2); gr->Title("'\\_' style");
+  gr->Rotate(50,60);  gr->Box();  gr->ContF(a,"_");
+
+  gr->Fill(a1,"0.6*sin(2*pi*x+pi*(z+1)/2)*sin(3*pi*y+pi*z) + 0.4*cos(3*pi*(x*y)+pi*(z+1)^2/2)");
+  gr->SubPlot(2,2,3); gr->Title("several slices");
+  gr->Rotate(50,60);  gr->Box();  gr->ContF(a1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/contf, Example of ContF()}
+
+@c ------------------------------------------------------------------
+@node ContD sample, ContV sample, ContF sample, 2D samples
+@subsection ContD sample
+
+@code{ContD} is similar to @code{ContF} but with manual contour colors. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,v(5),a1(30,40,3); mgls_prepare2d(&a); v.a[0]=-0.5;
+  v.a[1]=-0.15; v.a[2]=0; v.a[3]=0.15;  v.a[4]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("ContD plot (default)");
+  gr->Rotate(50,60);  gr->Box();  gr->ContD(a);
+
+  gr->SubPlot(2,2,1); gr->Title("manual levels");
+  gr->Rotate(50,60);  gr->Box();  gr->ContD(v,a);
+
+  gr->SubPlot(2,2,2); gr->Title("'\\_' style");
+  gr->Rotate(50,60);  gr->Box();  gr->ContD(a,"_");
+
+  gr->Fill(a1,"0.6*sin(2*pi*x+pi*(z+1)/2)*sin(3*pi*y+pi*z) + 0.4*cos(3*pi*(x*y)+pi*(z+1)^2/2)");
+  gr->SubPlot(2,2,3); gr->Title("several slices");
+  gr->Rotate(50,60);  gr->Box();  gr->ContD(a1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/contd, Example of ContD()}
+
+@c ------------------------------------------------------------------
+@node ContV sample, Axial sample, ContD sample, 2D samples
+@subsection ContV sample
+
+@code{ContV} draw vertical cylinders (belts) at contour lines. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,v(5); mgls_prepare2d(&a); v.a[0]=-0.5;
+  v.a[1]=-0.15; v.a[2]=0; v.a[3]=0.15;  v.a[4]=0.5;
+  gr->SubPlot(2,2,0); gr->Title("ContV plot (default)");
+  gr->Rotate(50,60);  gr->Box();  gr->ContV(a);
+
+  gr->SubPlot(2,2,1); gr->Title("manual levels");
+  gr->Rotate(50,60);  gr->Box();  gr->ContV(v,a);
+
+  gr->SubPlot(2,2,2); gr->Title("'\\_' style");
+  gr->Rotate(50,60);  gr->Box();  gr->ContV(a,"_");
+
+  gr->SubPlot(2,2,3); gr->Title("ContV and ContF");
+  gr->Rotate(50,60);  gr->Box();  gr->Light(true);
+  gr->ContV(a); gr->ContF(a); gr->Cont(a,"k");
+  return 0;
+}
+@end verbatim
+
+@fig{png/contv, Example of ContV()}
+
+@c ------------------------------------------------------------------
+@node Axial sample, Grad sample, ContV sample, 2D samples
+@subsection Axial sample
+
+@code{Axial} draw surfaces of rotation for contour lines. You can draw wire surfaces (@samp{#} style) or ones rotated in other directions (@samp{x}, @samp{z} styles). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->SubPlot(2,2,0); gr->Title("Axial plot (default)");
+  gr->Light(true);  gr->Alpha(true);  gr->Rotate(50,60);
+  gr->Box();  gr->Axial(a);
+
+  gr->SubPlot(2,2,1); gr->Title("'x' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Axial(a,"x");
+
+  gr->SubPlot(2,2,2); gr->Title("'z' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Axial(a,"z");
+
+  gr->SubPlot(2,2,3); gr->Title("'\\#' style"); gr->Rotate(50,60);
+  gr->Box();  gr->Axial(a,"#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/axial, Example of Axial()}
+
+@c ------------------------------------------------------------------
+@node Grad sample, , Axial sample, 2D samples
+@subsection Grad sample
+
+@code{Grad} draw gradient lines for matrix. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->SubPlot(1,1,0,""); gr->Title("Grad plot");
+  gr->Box();  gr->Grad(a);  gr->Dens(a,"{u8}w{q8}");
+  return 0;
+}
+@end verbatim
+
+@fig{png/grad, Example of Grad()}
 
-Also, all arguments of C function have to be defined. So there are several functions with practically identical names doing practically the same. But some of them have simplified interface for the quick plotting and some of them have access to all plotting parameters for manual tunning.
 
-As an example of C function usage let me draw the plot from @ref{Plots for 2D data}. The C code which does it is shown below:
+@c ------------------------------------------------------------------
+@node 3D samples, Vector field samples, 2D samples, Examples
+@section 3D samples
+
+This section is devoted to visualization of 3D data arrays. 3D means the data which depend on 3 indexes (parameters) like tensor a(i,j,k)=a(x(i),y(j),x(k)), i=1...n, j=1...m, k=1...l or in parametric form @{x(i,j,k),y(i,j,k),z(i,j,k),a(i,j,k)@}. Most of samples will use the same data for plotting. So, I put its initialization in separate function
+@verbatim
+void mgls_prepare3d(mglData *a, mglData *b=0)
+{
+  register long i,j,k,n=61,m=50,l=40,i0;
+  if(a) a->Create(n,m,l);   if(b) b->Create(n,m,l);
+  float x,y,z;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)  for(k=0;k<l;k++)
+  {
+    x=2*i/(n-1.)-1; y=2*j/(m-1.)-1; z=2*k/(l-1.)-1; i0 = i+n*(j+m*k);
+    if(a) a->a[i0] = -2*(x*x + y*y + z*z*z*z - z*z - 0.1);
+    if(b) b->a[i0] = 1-2*tanh((x+y)*(x+y));
+  }
+}
+@end verbatim
+or using C functions
+@verbatim
+void mgls_prepare3d(HMDT a, HMDT b=0)
+{
+  register long i,j,k,n=61,m=50,l=40,i0;
+  if(a) mgl_data_create(a,n,m,l);
+  if(b) mgl_data_create(b,n,m,l);
+  float x,y,z;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)  for(k=0;k<l;k++)
+  {
+    x=2*i/(n-1.)-1; y=2*j/(m-1.)-1; z=2*k/(l-1.)-1; i0 = i+n*(j+m*k);
+    if(a) mgl_data_set_value(a, -2*(x*x + y*y + z*z*z*z - z*z - 0.1), i,j,k);
+    if(b) mgl_data_set_value(b, 1-2*tanh((x+y)*(x+y)), i,j,k);
+  }
+}
+@end verbatim
+
+@menu
+* Surf3 sample::
+* Surf3C sample::
+* Surf3A sample::
+* Cloud sample::
+* Dens3 sample::
+* Cont3 sample::
+* ContF3 sample::
+* Dens projection sample::
+* Cont projection sample::
+* ContF projection sample::
+* TriPlot and QuadPlot::
+* Dots sample::
+@end menu
+
+@c ------------------------------------------------------------------
+@node Surf3 sample, Surf3C sample, , 3D samples
+@subsection Surf3 sample
+
+@code{Surf3} is one of most suitable (for my opinion) functions to visualize 3D data. It draw the isosurface(s) -- surface(s) of constant amplitude (3D analogue of contour lines). You can draw wired isosurfaces if specify @samp{#} style. The sample code is:
 @verbatim
-    #include <mgl/mgl_c.h>
-    int main()
-    {
-        HMGL gr = mgl_create_graph_zb(600, 400);
-        mgl_set_alpha(gr, true);
-        mgl_set_light(gr, true);
-        HMDT a = mgl_create_data_size(30,20,1);
-        mgl_data_modify(a,"0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))",0);
-
-        mgl_subplot(gr, 2,2,0);
-        mgl_rotate(gr, 40,60,0);
-        mgl_surf(gr,a,"BbcyrR#");
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,1);
-        mgl_rotate(gr, 40,60,0);
-        mgl_dens(gr,a,"BbcyrR#",NAN);
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,2);
-        mgl_rotate(gr, 40,60,0);
-        mgl_cont(gr,a,"BbcyrR#",7,NAN);
-        mgl_box(gr, true);
-        mgl_subplot(gr, 2,2,3);
-        mgl_rotate(gr, 40,60,0);
-        mgl_axial(gr,a,"BbcyrR#",3);
-        mgl_box(gr, true);
-
-        /* don't forgot to save graphics */
-        mgl_write_png(gr,"sample.png",0);
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Surf3 plot");  gr->Rotate(50,60);
+  gr->Light(true);  gr->Alpha(true);
+  gr->Box();  gr->Surf3(c);
+  return 0;
+}
 @end verbatim
 
-Practically the same simple to create a window. For example let rewrite the code from for window creation (@pxref{Using FLTK/GLUT window}):
+@fig{png/surf3, Example of Surf3()}
+
+@c ------------------------------------------------------------------
+@node Surf3C sample, Surf3A sample, Surf3 sample, 3D samples
+@subsection Surf3C sample
+
+@code{Surf3C} is similar to @code{Surf3} but its coloring is determined by another data. The sample code is:
 @verbatim
-    int sample(HMGL gr, void *)
-    {
-        mgl_rotate(gr,60,40,0);
-        mgl_box(gr,1);
-        return 0;
-    }
-    //-----------------------------------------------------
-    int main(int argc,char **argv)
-    {
-        mgl_create_graph_fltk(sample, "MathGL examples", NULL);
-        mgl_fltk_run();
-        return 0;
-    }
+int sample(mglGraph *gr)
+{
+  mglData c,d;  mgls_prepare3d(&c,&d);
+  gr->Title("Surf3C plot"); gr->Rotate(50,60);
+  gr->Light(true);  gr->Alpha(true);
+  gr->Box();  gr->Surf3C(c,d);
+  return 0;
+}
 @end verbatim
 
-The Fortran code have some peculiarities. Exactly it not allow one to send arbitrary parameter (which was @code{NULL} in previous example) to function. This is limitation of Fortran language. So, the corresponding code will be @strong{NOT TESTED NOW!!!}:
+@fig{png/surf3c, Example of Surf3C()}
+
+@c ------------------------------------------------------------------
+@node Surf3A sample, Cloud sample, Surf3C sample, 3D samples
+@subsection Surf3A sample
+
+@code{Surf3A} is similar to @code{Surf3} but its transparency is determined by another data. The sample code is:
 @verbatim
-    program TEST
-    integer x,f,func
-        call mgl_create_graph_fltk(sample, 'MathGL examples');
-        call mgl_fltk_run();
-    end program TEST
-    integer function sample(gr)
-    integer*8 gr
-        call mgl_rotate(gr,60,40,0);
-        call mgl_box(gr,1);
-        sample=0
-    return
-    end
+int sample(mglGraph *gr)
+{
+  mglData c,d;  mgls_prepare3d(&c,&d);
+  gr->Title("Surf3A plot"); gr->Rotate(50,60);
+  gr->Light(true);  gr->Alpha(true);
+  gr->Box();  gr->Surf3A(c,d);
+  return 0;
+}
 @end verbatim
 
+@fig{png/surf3a, Example of Surf3A()}
+
 @c ------------------------------------------------------------------
-@node MathGL and PyQt, Hints, C/Fortran interface, Examples
-@section MathGL and PyQt
+@node Cloud sample, Dens3 sample, Surf3A sample, 3D samples
+@subsection Cloud sample
 
-Generally SWIG based classes (including the Python one) are the same as C++ classes. However, there are few tips for using MathGL with PyQt. Below I place a very simple python code which demonstrate how MathGL can be used with PyQt. This code is mostly written by Prof. Dr. Heino Falcke. You can just copy it to a file @code{mgl-pyqt-test.py} and execute it from python shell by command @code{execfile("mgl-pyqt-test.py")}
+@code{Cloud} draw cloud-like object which is less transparent for higher data values. Similar plot can be created using many (about 10-20) @code{Surf3A(a,a)} isosurfaces. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->SubPlot(2,2,0); gr->Title("Cloud plot");
+  gr->Rotate(50,60);  gr->Alpha(true);
+  gr->Box();  gr->Cloud(c,"wyrRk");
+
+  gr->SubPlot(2,2,1); gr->Title("'!' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Cloud(c,"!wyrRk");
 
+  gr->SubPlot(2,2,2); gr->Title("'.' style");
+  gr->Rotate(50,60);  gr->Box();  gr->Cloud(c,".wyrRk");
+
+  gr->SubPlot(2,2,3); gr->Title("meshnum 10");
+  gr->Rotate(50,60);  gr->Box();  gr->Cloud(c,"wyrRk","meshnum 10");
+  return 0;
+}
+@end verbatim
+
+@fig{png/cloud, Example of Cloud()}
+
+@c ------------------------------------------------------------------
+@node Dens3 sample, Cont3 sample, Cloud sample, 3D samples
+@subsection Dens3 sample
+
+@code{Dens3} draw just usual density plot but at slices of 3D data. The sample code is:
 @verbatim
-from PyQt4 import QtGui,QtCore
-from mathgl import *
-import sys
-app = QtGui.QApplication(sys.argv)
-qpointf=QtCore.QPointF()
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Dens3 sample");  gr->Rotate(50,60);
+  gr->Alpha(true);  gr->SetAlphaDef(0.7);
+  gr->SetOrigin(0,0,0); gr->Axis("_xyz"); gr->Box();
+  gr->Dens3(c,"x"); gr->Dens3(c); gr->Dens3(c,"z");
+  return 0;
+}
+@end verbatim
 
-class hfQtPlot(QtGui.QWidget):
-    def __init__(self, parent=None):
-        QtGui.QWidget.__init__(self, parent)
-        self.img=(QtGui.QImage())
-    def setgraph(self,gr):
-        self.buffer='\t' 
-        self.buffer=self.buffer.expandtabs(4*gr.GetWidth()*gr.GetHeight())
-        gr.GetBGRN(self.buffer,len(self.buffer))
-        self.img=QtGui.QImage(self.buffer, gr.GetWidth(),gr.GetHeight(),QtGui.QImage.Format_ARGB32)
-        self.update()
-    def paintEvent(self, event):
-        paint = QtGui.QPainter()
-        paint.begin(self)
-        paint.drawImage(qpointf,self.img)
-        paint.end()
+@fig{png/densa, Example of Dens3()}
 
-BackgroundColor=[1.0,1.0,1.0]
-size=100
-gr=mglGraph()
-y=mglData(size)
-#y.Modify("((0.7*cos(2*pi*(x+.2)*500)+0.3)*(rnd*0.5+0.5)+362.135+10000.)")
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-x=mglData(size)
-x.Modify("x^2");
+@c ------------------------------------------------------------------
+@node Cont3 sample, ContF3 sample, Dens3 sample, 3D samples
+@subsection Cont3 sample
 
-def plotpanel(gr,x,y,n):
-    gr.SubPlot(2,2,n)
-    gr.SetXRange(x)
-    gr.SetYRange(y)
-    gr.AdjustTicks()
-    gr.Axis()
-    gr.Box()
-    gr.Label("x","x-Axis",1)
-    gr.Label("y","y-Axis",1)
-    gr.ClearLegend()
-    gr.AddLegend("Legend: "+str(n),"k")
-    gr.Legend()
-    gr.Plot(x,y)
+@code{Cont3} draw just usual contour lines but at slices of 3D data. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Cont3 sample");  gr->Rotate(50,60);
+  gr->Alpha(true);  gr->SetAlphaDef(0.7);
+  gr->SetOrigin(0,0,0); gr->Axis("_xyz"); gr->Box();
+  gr->Cont3(c,"x"); gr->Cont3(c); gr->Cont3(c,"z");
+  return 0;
+}
+@end verbatim
 
+@fig{png/conta, Example of Cont3()}
 
-gr.Clf(BackgroundColor[0],BackgroundColor[1],BackgroundColor[2])
-gr.SetPlotFactor(1.5)
-plotpanel(gr,x,y,0)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,1)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,2)
-y.Modify("(cos(2*pi*x*10)+1.1)*1000.*rnd-501")
-plotpanel(gr,x,y,3)
+@c ------------------------------------------------------------------
+@node ContF3 sample, Dens projection sample, Cont3 sample, 3D samples
+@subsection ContF3 sample
 
-gr.WritePNG("test.png","Test Plot")
+@code{ContF3} draw just usual filled contours but at slices of 3D data. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("ContF3 sample");  gr->Rotate(50,60);
+  gr->Alpha(true);  gr->SetAlphaDef(0.7);
+  gr->SetOrigin(0,0,0); gr->Axis("_xyz"); gr->Box();
+  gr->ContF3(c,"x");  gr->ContF3(c);    gr->ContF3(c,"z");
+  gr->Cont3(c,"kx");  gr->Cont3(c,"k"); gr->Cont3(c,"kz");
+  return 0;
+}
+@end verbatim
 
-qw = hfQtPlot()
-qw.show()
-qw.setgraph(gr)
-qw.raise_()
+@fig{png/contfa, Example of ContF3()}
+
+@c ------------------------------------------------------------------
+@node Dens projection sample, Cont projection sample, ContF3 sample, 3D samples
+@subsection Dens projection sample
+
+@code{Dens[XYZ]} draw density plot on plane perpendicular to corresponding axis. One of possible application is drawing projections of 3D field. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Dens[XYZ] sample");  gr->Rotate(50,60);
+  gr->Box();  gr->DensX(c.Sum("x"),0,-1);
+  gr->DensY(c.Sum("y"),0,1);  gr->DensZ(c.Sum("z"),0,-1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/dens_xyz, {Example of DensX(), DensY(), DensZ()}}
+
+@c ------------------------------------------------------------------
+@node Cont projection sample, ContF projection sample, Dens projection sample, 3D samples
+@subsection Cont projection sample
+
+@code{Cont[XYZ]} draw contour lines on plane perpendicular to corresponding axis. One of possible application is drawing projections of 3D field. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Cont[XYZ] sample");  gr->Rotate(50,60);
+  gr->Box();  gr->ContX(c.Sum("x"),"",-1);
+  gr->ContY(c.Sum("y"),"",1); gr->ContZ(c.Sum("z"),"",-1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/cont_xyz, {Example of ContX(), ContY(), ContZ()}}
+
+@c ------------------------------------------------------------------
+@node ContF projection sample, TriPlot and QuadPlot, Cont projection sample, 3D samples
+@subsection ContF projection sample
+
+@code{Dens[XYZ]} draw filled contours on plane perpendicular to corresponding axis. One of possible application is drawing projections of 3D field. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData c;  mgls_prepare3d(&c);
+  gr->Title("Cont[XYZ] sample");  gr->Rotate(50,60);
+  gr->Box();  gr->ContFX(c.Sum("x"),"",-1);
+  gr->ContFY(c.Sum("y"),"",1);  gr->ContFZ(c.Sum("z"),"",-1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/contf_xyz, {Example of ContFX(), ContFY(), ContFZ()}}
+
+@c ------------------------------------------------------------------
+@node TriPlot and QuadPlot, Axial sample, ContF projection sample, 3D samples
+@subsection TriPlot and QuadPlot
+
+@code{TriPlot} and @code{QuadPlot} draw set of triangles (or quadrangles for @code{QuadPlot}) for irregular data arrays. Note, that you have to provide not only vertexes, but also the indexes of triangles or quadrangles. I.e. perform triangulation by some other library. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  float q[] = {0,1,2,3, 4,5,6,7, 0,2,4,6, 1,3,5,7, 0,4,1,5, 2,6,3,7};
+  float xc[] = {-1,1,-1,1,-1,1,-1,1}, yc[] = {-1,-1,1,1,-1,-1,1,1}, zc[] = {-1,-1,-1,-1,1,1,1,1};
+  mglData qq(6,4,q), xx(8,xc), yy(8,yc), zz(8,zc);
+  gr->Light(true);  //gr->Alpha(true);
+  gr->SubPlot(2,1,0); gr->Title("QuadPlot sample"); gr->Rotate(50,60);
+  gr->QuadPlot(qq,xx,yy,zz,"yr");
+  gr->QuadPlot(qq,xx,yy,zz,"k#");
+
+  float t[] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};
+  float xt[] = {-1,1,0,0}, yt[] = {-1,-1,1,0}, zt[] = {-1,-1,-1,1};
+  mglData tt(4,3,t), uu(4,xt), vv(4,yt), ww(4,zt);
+  gr->SubPlot(2,1,1); gr->Title("TriPlot sample");  gr->Rotate(50,60);
+  gr->TriPlot(tt,uu,vv,ww,"b");
+  gr->TriPlot(tt,uu,vv,ww,"k#");
+  return 0;
+}
+@end verbatim
+
+@fig{png/triplot, Example of TriPlot() and QuadPlot()}
+
+@c ------------------------------------------------------------------
+@node Dots sample, , TriPlot and QuadPlot, 3D samples
+@subsection Dots sample
+
+@code{Dots} is another way to draw irregular points. @code{Dots} use color scheme for coloring (see @ref{Color scheme}). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  int i, n=1000;
+  mglData x(n),y(n),z(n);
+  for(i=0;i<n;i++)
+  {
+    float t=M_PI*(mgl_rnd()-0.5), f=2*M_PI*mgl_rnd();
+    x.a[i] = 0.9*cos(t)*cos(f);
+    y.a[i] = 0.9*cos(t)*sin(f);
+    z.a[i] = 0.6*sin(t);
+  }
+  gr->Title("Dots sample"); gr->Rotate(50,60);
+  gr->Box();  gr->Dots(x,y,z);
+  return 0;
+}
+@end verbatim
+
+@fig{png/dots, Example of Dots()}
+
+@c ------------------------------------------------------------------
+@node Vector field samples, Hints, 3D samples, Examples
+@section Vector field samples
+
+Vector field visualization (especially in 3d case) is more or less complex task. MathGL provides 3 general types of plots: vector field itself (@code{Vect}), flow threads (@code{Flow}), and flow pipes with radius proportional to field amplitude (@code{Pipe}).
+
+However, the plot may look tangly -- there are too many overlapping lines. I may suggest 2 ways to solve this problem. The first one is to change @code{SetMeshNum} for decreasing the number of hachures. The second way is to use the flow thread chart @code{Flow}, or possible many flow thread from manual position (@code{FlowP}). Unfortunately, I don't know any other methods to visualize 3d vector field. If you know any, e-mail me and I shall add it to MathGL.
+
+Most of samples will use the same data for plotting. So, I put its initialization in separate function
+@verbatim
+void mgls_prepare2v(mglData *a, mglData *b)
+{
+  register long i,j,n=20,m=30,i0;
+  if(a) a->Create(n,m);   if(b) b->Create(n,m);
+  float x,y;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)
+  {
+    x=i/(n-1.); y=j/(m-1.); i0 = i+n*j;
+    if(a) a->a[i0] = 0.6*sin(2*M_PI*x)*sin(3*M_PI*y)+0.4*cos(3*M_PI*x*y);
+    if(b) b->a[i0] = 0.6*cos(2*M_PI*x)*cos(3*M_PI*y)+0.4*cos(3*M_PI*x*y);
+  }
+}
+void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez)
+{
+  register long i,j,k,n=10,i0;
+  if(!ex || !ey || !ez) return;
+  ex->Create(n,n,n);  ey->Create(n,n,n);  ez->Create(n,n,n);
+  float x,y,z, r1,r2;
+  for(i=0;i<n;i++)  for(j=0;j<n;j++)  for(k=0;k<n;k++)
+  {
+    x=2*i/(n-1.)-1; y=2*j/(n-1.)-1; z=2*k/(n-1.)-1; i0 = i+n*(j+k*n);
+    r1 = pow(x*x+y*y+(z-0.3)*(z-0.3)+0.03,1.5);
+    r2 = pow(x*x+y*y+(z+0.3)*(z+0.3)+0.03,1.5);
+    ex->a[i0]=0.2*x/r1 - 0.2*x/r2;
+    ey->a[i0]=0.2*y/r1 - 0.2*y/r2;
+    ez->a[i0]=0.2*(z-0.3)/r1 - 0.2*(z+0.3)/r2;
+  }
+}
+@end verbatim
+or using C functions
+@verbatim
+void mgls_prepare2v(mglData *a, mglData *b)
+{
+  register long i,j,n=20,m=30,i0;
+  if(a) mgl_data_create(a,n,m,1);
+  if(b) mgl_data_create(b,n,m,1);
+  float x,y;
+  for(i=0;i<n;i++)  for(j=0;j<m;j++)
+  {
+    x=i/(n-1.); y=j/(m-1.); i0 = i+n*j;
+    if(a) mgl_data_set_value(a, 0.6*sin(2*M_PI*x)*sin(3*M_PI*y)+0.4*cos(3*M_PI*x*y), i,j,0);
+    if(b) mgl_data_set_value(b, 0.6*cos(2*M_PI*x)*cos(3*M_PI*y)+0.4*cos(3*M_PI*x*y), i,j,0);
+  }
+}
+void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez)
+{
+  register long i,j,k,n=10,i0;
+  if(!ex || !ey || !ez) return;
+  mgl_data_create(ex,n,n,n);
+  mgl_data_create(ey,n,n,n);
+  mgl_data_create(ez,n,n,n);
+  float x,y,z, r1,r2;
+  for(i=0;i<n;i++)  for(j=0;j<n;j++)  for(k=0;k<n;k++)
+  {
+    x=2*i/(n-1.)-1; y=2*j/(n-1.)-1; z=2*k/(n-1.)-1; i0 = i+n*(j+k*n);
+    r1 = pow(x*x+y*y+(z-0.3)*(z-0.3)+0.03,1.5);
+    r2 = pow(x*x+y*y+(z+0.3)*(z+0.3)+0.03,1.5);
+    mgl_data_set_value(ex, 0.2*x/r1 - 0.2*x/r2, i,j,k);
+    mgl_data_set_value(ey, 0.2*y/r1 - 0.2*y/r2, i,j,k);
+    mgl_data_set_value(ez, 0.2*(z-0.3)/r1 - 0.2*(z+0.3)/r2, i,j,k);
+  }
+}
+@end verbatim
+
+@menu
+* Vect sample::
+* Traj sample::
+* Flow sample::
+* Pipe sample::
+* Dew sample::
+@end menu
+
+
+@c ------------------------------------------------------------------
+@node Vect sample, Traj sample, , Vector field samples
+@subsection Vect sample
+
+@code{Vect} is most standard way to visualize vector fields -- it draw a lot of arrows or hachures for each data cell. It have a lot of options which can be seen on the figure (and in the sample code). @code{Vect} use color scheme for coloring (see @ref{Color scheme}). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2v(&a,&b);
+  gr->SubPlot(3,2,0,""); gr->Title("Vect plot (default)");
+  gr->Box();  gr->Vect(a,b);
+
+  gr->SubPlot(3,2,1,"");  gr->Title("'.' style; '=' style");
+  gr->Box();  gr->Vect(a,b,"=.");
+
+  gr->SubPlot(3,2,2,"");  gr->Title("'f' style");
+  gr->Box();  gr->Vect(a,b,"f");
+
+  gr->SubPlot(3,2,3,"");  gr->Title("'>' style");
+  gr->Box();  gr->Vect(a,b,">");
+
+  gr->SubPlot(3,2,4,"");  gr->Title("'<' style");
+  gr->Box();  gr->Vect(a,b,"<");
+
+  mglData ex,ey,ez; mgls_prepare3v(&ex,&ey,&ez);
+  gr->SubPlot(3,2,5); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Vect(ex,ey,ez);
+  return 0;
+}
+@end verbatim
+
+@fig{png/vect, Example of Vect()}
+
+@c ------------------------------------------------------------------
+@node Traj sample, Flow sample, Vect sample, Vector field samples
+@subsection Traj sample
+
+@code{Traj} is 1D analogue of @code{Vect}. It draw vectors from specified points. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData x,y,y1,y2;  mgls_prepare1d(&y,&y1,&y2,&x);
+  gr->SubPlot(1,1,0,""); gr->Title("Traj plot");
+  gr->Box();  gr->Plot(x,y);  gr->Traj(x,y,y1,y2);
+  return 0;
+}
+@end verbatim
+
+@fig{png/traj, Example of Traj()}
+
+
+@c ------------------------------------------------------------------
+@node Flow sample, Pipe sample, Traj sample, Vector field samples
+@subsection Flow sample
+
+@code{Flow} is another standard way to visualize vector fields -- it draw lines (threads) which is tangent to local vector field direction. MathGL draw threads from edges of bounding box and from central slices. Sometimes it is not most appropriate variant -- you may want to use @code{FlowP} to specify manual position of threads. @code{Flow} use color scheme for coloring (see @ref{Color scheme}). At this warm color corresponds to normal flow (like attractor), cold one corresponds to inverse flow (like source). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2v(&a,&b);
+  gr->SubPlot(2,2,0,""); gr->Title("Flow plot (default)");
+  gr->Box();  gr->Flow(a,b);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("'v' style");
+  gr->Box();  gr->Flow(a,b,"v");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'\\#' style");
+  gr->Box();  gr->Flow(a,b,"#");
+
+  mglData ex,ey,ez; mgls_prepare3v(&ex,&ey,&ez);
+  gr->SubPlot(2,2,3); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Flow(ex,ey,ez);
+  return 0;
+}
+@end verbatim
+
+@fig{png/flow, Example of Flow()}
+
+@c ------------------------------------------------------------------
+@node Pipe sample, Dew sample, Flow sample, Vector field samples
+@subsection Pipe sample
+
+@code{Pipe} is similar to @code{Flow} but draw pipes (tubes) which radius is proportional to the amplitude of vector field. @code{Pipe} use color scheme for coloring (see @ref{Color scheme}). At this warm color corresponds to normal flow (like attractor), cold one corresponds to inverse flow (like source). The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2v(&a,&b);
+  gr->SubPlot(2,2,0,""); gr->Title("Pipe plot (default)");
+  gr->Light(true);  gr->Box();  gr->Pipe(a,b);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("'i' style");
+  gr->Box();  gr->Pipe(a,b,"i");
+
+  gr->SubPlot(2,2,2,"");  gr->Title("'\\#' style");
+  gr->Box();  gr->Pipe(a,b,"#");
+
+  mglData ex,ey,ez; mgls_prepare3v(&ex,&ey,&ez);
+  gr->SubPlot(2,2,3); gr->Title("3d variant");  gr->Rotate(50,60);
+  gr->Box();  gr->Pipe(ex,ey,ez,"",0.1);
+  return 0;
+}
+@end verbatim
+
+@fig{png/pipe, Example of Pipe()}
+
+@c ------------------------------------------------------------------
+@node Dew sample, , Pipe sample, Vector field samples
+@subsection Dew sample
+
+@code{Dew} is similar to @code{Vect} but use drops instead of arrows. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a,b;  mgls_prepare2v(&a,&b);
+  gr->SubPlot(1,1,0,""); gr->Title("Dew plot");
+  gr->Box();  gr->Light(true);  gr->Dew(a,b);
+  return 0;
+}
 @end verbatim
 
+@fig{png/dew, Example of Dew()}
+
 
 @c ------------------------------------------------------------------
-@node Hints, , MathGL and PyQt, Examples
+@node Hints, FAQ, Vector field samples, Examples
 @section Hints
 
-In this section I have included some small hints and advices for the improving of the quality of plots and for the demonstration of some non-trivial features of MathGL library. In contrast to previous examples I showed mostly the idea but not the whole drawing function. More examples with the source code can be find at @uref{http://mathgl.sf.net/} or in section @ref{Samples}.
+In this section I've included some small hints and advices for the improving of the quality of plots and for the demonstration of some non-trivial features of MathGL library. In contrast to previous examples I showed mostly the idea but not the whole drawing function.
 
 @menu
-* ``Compound'' graphics::       
-* Two axes in one plot::        
-* Titles for the plot::         
-* Changing of the color range:: 
-* Management of a point cutting::
-* Vector field visualization::  
-* Several light sources::       
-* CutMin and CutMax features::  
-* Mapping visualization::       
-* Log-scaled plot::             
-* ``Templates''::               
-* Nonlinear fitting hints::     
-* PDE solving hints::           
-* MGL parser using::            
-* Stereo image::                
+* ``Compound'' graphics::
+* Transparency and lighting::
+* Types of transparency::
+* Adding fog::
+* Several light sources::
+* Using primitives::
+* STFA sample::
+* Mapping visualization::
+* Making histogram::
+* Nonlinear fitting sample::
+* PDE solving hints::
+* MGL parser using::
+* ``Templates''::
+* Stereo image::
 @end menu
 
 @c ------------------------------------------------------------------
-@node ``Compound'' graphics, Two axes in one plot, , Hints
+@node ``Compound'' graphics, Transparency and lighting, , Hints
 @subsection ``Compound'' graphics
 
 As I noted above, MathGL functions (except the special one, like Clf()) do  not erase the previous plotting but just add the new one. It allows one to draw ``compound'' plots easily. For example, popular Matlab command @code{surfc} can be emulated in MathGL by 2 calls:
 @verbatim
-    Surf(a);
-    Cont(a, 0, 7, -1);     // draw contours at z = -1
+  Surf(a);
+  Cont(a, "_");     // draw contours at bottom
 @end verbatim
 Here @var{a} is 2-dimensional data for the plotting, @code{-1} is the value of z-coordinate at which the contour should be plotted (at the bottom in this example). Analogously, one can draw density plot instead of contour lines and so on.
 
 Another nice plot is contour lines plotted directly on the surface:
 @verbatim
-    Light(true);       // switch on light for the surface
-    Surf(a, "BbcyrR"); // select 'jet' colormap for the surface
-    Cont(a, "y");      // and yellow color for contours
+  Light(true);       // switch on light for the surface
+  Surf(a, "BbcyrR"); // select 'jet' colormap for the surface
+  Cont(a, "y");      // and yellow color for contours
 @end verbatim
 The possible difficulties arise in black&white case, when the color of the surface can be close to the color of a contour line. In that case I may suggest the following code:
 @verbatim
-    Light(true);       // switch on light for the surface
-    Surf(a, "kw");     // select 'gray' colormap for the surface
-    CAxis(-1,0);       // first draw for darker surface colors
-    Cont(a, "w");      // white contours
-    CAxis(0,1);        // now draw for brighter surface colors
-    Cont(a, "k");      // black contours
-    CAxis(-1,1);       // return color range to original state
+  Light(true);   // switch on light for the surface
+  Surf(a, "kw"); // select 'gray' colormap for the surface
+  CAxis(-1,0);   // first draw for darker surface colors
+  Cont(a, "w");  // white contours
+  CAxis(0,1);    // now draw for brighter surface colors
+  Cont(a, "k");  // black contours
+  CAxis(-1,1);   // return color range to original state
 @end verbatim
 The idea is to divide the color range on 2 parts (dark and bright) and to select the contrasting color for contour lines for each of part.
 
 Similarly, one can plot flow thread over density plot of vector field amplitude (this is another amusing plot from Matlab) and so on. The list of compound graphics can be prolonged but I hope that the general idea is clear.
 
-@c ------------------------------------------------------------------
-@node Two axes in one plot, Titles for the plot, ``Compound'' graphics, Hints
-@subsection Two axes in one plot
-
-Developing the previous hint one can make a plot with 2 or more axes. The idea is that the change of settings does not influence on the already drawn graphics. So, for 2-axes plot let us set the first axis and draw everything concerning it. Then let us setup the second axis and draw things for the second axis. The corresponding code is (@pxref{2-axes sample}):
+Just for illustration I put here following sample code:
 @verbatim
-    // set up first axis
-    Axis(mglPoint(-1,-1,-1),mglPoint(1,1,1),mglPoint(-1,-1,-1));
-    Axis();            // draw it
-    Plot(y1,"b");      // draw something in first axis
-    // set up second axis
-    Axis(mglPoint(0,0,0),mglPoint(1,1,1),mglPoint(1,1,1));
-    Axis();            // draw it
-    Stem(y2,"r");      // draw something in second axis
+int sample(mglGraph *gr)
+{
+  mglData a,b,d;  mgls_prepare2v(&a,&b);  d = a;
+  for(int i=0;i<a.nx*a.ny;i++)  d.a[i] = hypot(a.a[i],b.a[i]);
+  mglData c;  mgls_prepare3d(&c);
+  mglData v(10);  v.Fill(-0.5,1);
+
+  gr->SubPlot(2,2,1,"");  gr->Title("Flow + Dens");
+  gr->Flow(a,b,"br"); gr->Dens(d,"BbcyrR"); gr->Box();
+
+  gr->SubPlot(2,2,0); gr->Title("Surf + Cont"); gr->Rotate(50,60);
+  gr->Light(true);  gr->Surf(a);  gr->Cont(a,"y");  gr->Box();
+
+  gr->SubPlot(2,2,2); gr->Title("Mesh + Cont"); gr->Rotate(50,60);
+  gr->Box();  gr->Mesh(a);  gr->Cont(a,"_");
+
+  gr->SubPlot(2,2,3); gr->Title("Surf3 + ContF3");gr->Rotate(50,60);
+  gr->Box();  gr->ContF3(v,c,"z",0);  gr->ContF3(v,c,"x");  gr->ContF3(v,c);
+  gr->SetCutBox(mglPoint(0,-1,-1), mglPoint(1,0,1.1));
+  gr->ContF3(v,c,"z",c.nz-1); gr->Surf3(-0.5,c);
+  return 0;
+}
 @end verbatim
-Note, that the first and the second axes look better if being placed in different corners. In the code presented above the first axis is placed in the left-bottom corner, and the second one is placed in the right-top corner.
+
+@fig{png/combined, Example of ``combined'' plots}
 
 @c ------------------------------------------------------------------
-@node Titles for the plot, Changing of the color range, Two axes in one plot, Hints
-@subsection Titles for the plot
+@node Transparency and lighting, Types of transparency, ``Compound'' graphics, Hints
+@subsection Transparency and lighting
 
-The printing of nice titles for the plot is not so trivial task in general case. The problem is that the rotation and aspect change lead to different looks for titles of different subplots. So, the resulting look is not so good as it could be. The solution is simple -- to print titles exactly after @code{SubPlot}() call and before any rotation, aspect change and so on! Analogously, the title for the whole picture looks better if it is printed first (before any @code{SubPlot()} calls). Alternatively you can use function @code{Title()} for plotting title for the picture at any time.
+Here I want to show how transparency and lighting both and separately change the look of a surface. So, there is code and picture for that:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->SubPlot(2,2,0); gr->Title("default"); gr->Rotate(50,60);
+  gr->Box();  gr->Surf(a);
 
-@c ------------------------------------------------------------------
-@node Changing of the color range, Management of a point cutting, Titles for the plot, Hints
-@subsection Changing of the color range
+  gr->SubPlot(2,2,1); gr->Title("light on");  gr->Rotate(50,60);
+  gr->Box();  gr->Light(true);  gr->Surf(a);
 
-By default (for the user comfort), the color range is set equal to z-range of the plot. However, there are different ranges. So, one can obtain amusing plot by the change of color range manually. For example, there are plots with one-color bottom (or top) or practically bi-color picture and so on.
+  gr->SubPlot(2,2,2); gr->Title("alpha on; light on");  gr->Rotate(50,60);
+  gr->Box();  gr->Alpha(true);  gr->Surf(a);
 
-For example, compare 2 surfaces:
-@verbatim
-    SubPlot(2,1,0)
-    Surf(a);           // usual coloring range
-    SubPlot(2,1,1)
-    CAxis(0,1);
-    Surf(a);           // bottom of the surface have one-colour filling
+  gr->SubPlot(2,2,3); gr->Title("alpha on");  gr->Rotate(50,60);
+  gr->Box();  gr->Light(false); gr->Surf(a);
+  return 0;
+}
 @end verbatim
 
+@fig{png/alpha, Example of transparency and lightings}
+
 @c ------------------------------------------------------------------
-@node Management of a point cutting, Vector field visualization, Changing of the color range, Hints
-@subsection Management of a point cutting
+@node Types of transparency, Adding fog, Transparency and lighting, Hints
+@subsection Types of transparency
+
+MathGL library has advanced features for setting and handling the surface transparency. The simplest way to add transparency is the using of function @code{Alpha()}. As a result, all further surfaces (and isosurfaces, density plots and so on) become transparent. However, their  look can be additionally improved.
+
+The value of transparency can be different from surface to surface. To do it just use @code{SetAlphaDef} before the drawing of the surface, or use option @code{alpha} (see @ref{Command options}). If its value is close to 0 then the surface becomes more and more transparent. Contrary, if its value is close to 1 then the surface becomes practically non-transparent.
 
-Sometimes an experimental or numerical surface has outstanding points. Visualization of such surface will lead to the hole(s) in place of such points. The standard method of ``fighting''  -- to change data values -- is not always good and is not so convenient. MathGL library has another method -- to set variable @code{Cut=false}. As a consequence, all outstanding points will be projected on the bounding box.
+Also you can change the way how the light goes through overlapped surfaces. The function @code{SetTranspType} defines it. By default the usual transparency is used (@samp{0}) -- surfaces below is less visible than the upper ones. A ``glass-like'' transparency (@samp{1}) has a different look -- each surface just decreases the background light (the surfaces are commutable in this case).
 
-Such method is good not only for outstanding points but also for the case when one need to plane the bottom or the top of the plot. Exactly such case is demonstrated in the code:
+A ``neon-like'' transparency (@samp{2}) has more interesting look. In this case a surface is the light source (like a lamp on the dark background) and just adds some intensity to the color. At this, the library sets automatically the black color for the background and changes the default line color to white.
+
+As example I shall show several plots for different types of transparency. The code is the same except the values of @code{SetTranspType} function:
 @verbatim
-        mglData a(20,30);  // create some data
-        a.Modify("0.6*sin(2*pi*x)*sin(3*pi*y) + 0.4*cos(3*pi*(x*y))");
-        // set lower border above the data minimal value
-        Axis(mglPoint(-1,-1,0),mglPoint(1,1,1));
-        Cut = false;       // set off cutting flag
-`       Surf(a);           // and draw the surface
+int sample(mglGraph *gr)
+{
+  gr->Alpha(true);  gr->Light(true);
+  mglData a;  mgls_prepare2d(&a);
+  gr->SetTranspType(0); gr->Clf();
+  gr->SubPlot(2,2,0); gr->Rotate(50,60);  gr->Surf(a);  gr->Box();
+  gr->SubPlot(2,2,1); gr->Rotate(50,60);  gr->Dens(a);  gr->Box();
+  gr->SubPlot(2,2,2); gr->Rotate(50,60);  gr->Cont(a);  gr->Box();
+  gr->SubPlot(2,2,3); gr->Rotate(50,60);  gr->Axial(a); gr->Box();
+  return 0;
+}
 @end verbatim
-It is an interesting result, is not it?
+
+@fig{png/type0, Example of @code{SetTranspType(0)}.}
+@fig{png/type1, Example of @code{SetTranspType(1)}.}
+@fig{png/type2, Example of @code{SetTranspType(2)}.}
+
 
 @c ------------------------------------------------------------------
-@node Vector field visualization, Several light sources, Management of a point cutting, Hints
-@subsection Vector field visualization
+@node Adding fog, Several light sources, Types of transparency, Hints
+@subsection Adding fog
+
+MathGL can add a fog to the image. Its switching on is rather simple -- just use @code{Fog} function. There is the only feature -- fog is applied for whole image. Not to particular subplot. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Fog sample");
+  gr->Light(true);  gr->Rotate(50,60);  gr->Fog(1); gr->Box();
+  gr->Surf(a);
+  return 0;
+}
+@end verbatim
 
-Vector field visualization (especially in 3d case @code{Vect3} or @code{VectC}) may look tangly -- there are too many overlapping lines. I may suggest 2 ways to solve this problem. The first one is to change @code{MeshNum} for decreasing the number of hachures. The second way is to use the flow thread chart @code{Flow}. Unfortunately, I don't know any other methods to visualize 3d vector field. If you know any, e-mail me and I shall add it to MatGL.
+@fig{png/fog, Example of @code{Fog()}.}
 
 @c ------------------------------------------------------------------
-@node Several light sources, CutMin and CutMax features, Vector field visualization, Hints
+@node Several light sources, Using primitives, Adding fog, Hints
 @subsection Several light sources
 
-In contrast to the most of other programs, MathGL supports several (up to 10) light sources. Moreover, the color each of them can be different: white (this is usual), yellow, red, cyan, green and so on. The use of several light sources may be interesting for the highlighting of some peculiarities of the plot or just to make an amusing picture. Note, each light source can be switched on/off individually (@pxref{Several light sample}).
+In contrast to the most of other programs, MathGL supports several (up to 10) light sources. Moreover, the color each of them can be different: white (this is usual), yellow, red, cyan, green and so on. The use of several light sources may be interesting for the highlighting of some peculiarities of the plot or just to make an amusing picture. Note, each light source can be switched on/off individually. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Title("Several light sources");
+  gr->Rotate(50,60);  gr->Light(true);
+  gr->AddLight(1,mglPoint(0,1,0),'c');
+  gr->AddLight(2,mglPoint(1,0,0),'y');
+  gr->AddLight(3,mglPoint(0,-1,0),'m');
+  gr->Box();  gr->Surf(a,"h");
+  return 0;
+}
+@end verbatim
+
+@fig{png/several_light, Example of several light sources.}
+
+@c ------------------------------------------------------------------
+@node Using primitives, STFA sample, Several light sources, Hints
+@subsection Using primitives
+
+MathGL provide a set of functions for drawing primitives (see @ref{Primitives}). Primitives are low level object, which used by most of plotting functions. Picture below demonstrate some of commonly used primitives.
+
+@fig{png/primitives, Primitives in MathGL.}
+
+Generally, you can create arbitrary new kind of plot using primitives. For example, MathGL don't provide any special functions for drawing molecules. However, you can do it using only one type of primitives @code{Drop}. The sample code is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->Alpha(true);  gr->Light(true);
+
+  gr->SubPlot(2,2,0,"");  gr->Title("Methane, CH_4");
+  gr->StartGroup("Methane");
+  gr->Rotate(60,120);
+  gr->Sphere(mglPoint(0,0,0),0.25,"k");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0,0,1),0.35,"h",1,2);
+  gr->Sphere(mglPoint(0,0,0.7),0.25,"g");
+  gr->Drop(mglPoint(0,0,0),mglPoint(-0.94,0,-0.33),0.35,"h",1,2);
+  gr->Sphere(mglPoint(-0.66,0,-0.23),0.25,"g");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.47,0.82,-0.33),0.35,"h",1,2);
+  gr->Sphere(mglPoint(0.33,0.57,-0.23),0.25,"g");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.47,-0.82,-0.33),0.35,"h",1,2);
+  gr->Sphere(mglPoint(0.33,-0.57,-0.23),0.25,"g");
+  gr->EndGroup();
+
+  gr->SubPlot(2,2,1,"");  gr->Title("Water, H_{2}O");
+  gr->StartGroup("Water");
+  gr->Rotate(60,100);
+  gr->StartGroup("Water_O");
+  gr->Sphere(mglPoint(0,0,0),0.25,"r");
+  gr->EndGroup();
+  gr->StartGroup("Water_Bond_1");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.3,0.5,0),0.3,"m",1,2);
+  gr->EndGroup();
+  gr->StartGroup("Water_H_1");
+  gr->Sphere(mglPoint(0.3,0.5,0),0.25,"g");
+  gr->EndGroup();
+  gr->StartGroup("Water_Bond_2");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.3,-0.5,0),0.3,"m",1,2);
+  gr->EndGroup();
+  gr->StartGroup("Water_H_2");
+  gr->Sphere(mglPoint(0.3,-0.5,0),0.25,"g");
+  gr->EndGroup();
+  gr->EndGroup();
+
+  gr->SubPlot(2,2,2,"");  gr->Title("Oxygen, O_2");
+  gr->StartGroup("Oxygen");
+  gr->Rotate(60,120);
+  gr->Drop(mglPoint(0,0.5,0),mglPoint(0,-0.3,0),0.3,"m",1,2);
+  gr->Sphere(mglPoint(0,0.5,0),0.25,"r");
+  gr->Drop(mglPoint(0,-0.5,0),mglPoint(0,0.3,0),0.3,"m",1,2);
+  gr->Sphere(mglPoint(0,-0.5,0),0.25,"r");
+  gr->EndGroup();
+
+  gr->SubPlot(2,2,3,"");  gr->Title("Ammonia, NH_3");
+  gr->StartGroup("Ammonia");
+  gr->Rotate(60,120);
+  gr->Sphere(mglPoint(0,0,0),0.25,"b");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.33,0.57,0),0.32,"n",1,2);
+  gr->Sphere(mglPoint(0.33,0.57,0),0.25,"g");
+  gr->Drop(mglPoint(0,0,0),mglPoint(0.33,-0.57,0),0.32,"n",1,2);
+  gr->Sphere(mglPoint(0.33,-0.57,0),0.25,"g");
+  gr->Drop(mglPoint(0,0,0),mglPoint(-0.65,0,0),0.32,"n",1,2);
+  gr->Sphere(mglPoint(-0.65,0,0),0.25,"g");
+  gr->EndGroup();
+  return 0;
+}
+@end verbatim
+
+@fig{png/molecule, Example of molecules drawing.}
+
+Moreover, some of special plots can be more easily produced by primitives rather than by specialized function. For example, Venn diagram can be produced by @code{Error} plot:
+@verbatim
+int sample(mglGraph *gr)
+{
+  double xx[3]={-0.3,0,0.3}, yy[3]={0.3,-0.3,0.3}, ee[3]={0.7,0.7,0.7};
+  mglData x(3,xx), y(3,yy), e(3,ee);
+  gr->Title("Venn-like diagram"); gr->Alpha(true);
+  gr->Error(x,y,e,e,"!rgb@#o");
+  return 0;
+}
+@end verbatim
+You see that you have to specify and fill 3 data arrays. The same picture can be produced by just 3 calls of @code{Circle} function:
+@verbatim
+int sample(mglGraph *gr)
+{
+  gr->Title("Venn-like diagram"); gr->Alpha(true);
+  gr->Circle(mglPoint(-0.3,0.3),0.7,"rr@");
+  gr->Circle(mglPoint(0,-0.3),0.7,"gg@");
+  gr->Circle(mglPoint( 0.3,0.3),0.7,"bb@");
+  return 0;
+}
+@end verbatim
+Of course, the first variant is more suitable if you need to plot a lot of circles. But for few ones the usage of primitives looks easy.
+
+@fig{png/venn, Example of Venn diagram.}
 
 @c ------------------------------------------------------------------
-@node CutMin and CutMax features, Mapping visualization, Several light sources, Hints
-@subsection CutMin and CutMax features
+@node STFA sample, Mapping visualization, Using primitives, Hints
+@subsection STFA sample
 
-MathGL library has a feature for cutting of points in some region @var{CutMin*CutMax}. Such an excision can be used to improve the look of the graphics. Moreover, this cutting may help to show an internal structure of an object (like @code{isocaps} plot in Matlab). For example, let us use the standard 3D data array and show its interior (@pxref{CutMinMax sample}).
+Short-time Fourier Analysis (STFA) is one of informative method for analyzing long rapidly oscillating 1D data arrays. It is used to determine the sinusoidal frequency and phase content of local sections of a signal as it changes over time.
 
+MathGL can find and draw STFA result. Just to show this feature I give following sample. Initial data arrays is 1D arrays with step-like frequency. Exactly this you can see at bottom on the STFA plot. The sample code is:
 @verbatim
-    mglData  c(61,51,40);      // create the data
-    mglData v(10);     v.Fill(-0.5,1);
-    c.Modify("(-2*((2*x-1)^2 + (2*y-1)^2 + (2*z-1)^4 - (2*z-1)^2 - 0.1))");
-    gr->CutMin = mglPoint(0,-1,-1);     gr->CutMax = mglPoint(1,0,1.1);
-    gr->Surf3(-0.5,c,"BbcyrR");
-    gr->ContF3(v,c,'x',-1,"BbcyrR");    gr->ContF3(v,c,'y',-1,"BbcyrR");
-    gr->ContF3(v,c,'z',0,"BbcyrR");     gr->ContF3(v,c,'z',39,"BbcyrR");
+int sample(mglGraph *gr)
+{
+  mglData a(2000), b(2000);
+  gr->Fill(a,"cos(50*pi*x)*(x<-.5)+cos(100*pi*x)*(x<0)*(x>-.5)+\
+  cos(200*pi*x)*(x<.5)*(x>0)+cos(400*pi*x)*(x>.5)");
+  gr->SubPlot(1, 2, 0,"<_");  gr->Title("Initial signal");
+  gr->Plot(a);
+  gr->Axis();
+  gr->Label('x', "\\i t");
+
+  gr->SubPlot(1, 2, 1,"<_");  gr->Title("STFA plot");
+  gr->STFA(a, b, 64);
+  gr->Axis();
+  gr->Label('x', "\\i t");
+  gr->Label('y', "\\omega", 0);
+  return 0;
+}
 @end verbatim
 
-One can also exclude points from arbitrary area in space. This area defined by textual formula @code{CutOff()} (@pxref{Cutting}). The algorithm is the same as shown for ``rectangular cutting''.
+@fig{png/stfa, Example of STFA().}
 
 @c ------------------------------------------------------------------
-@node Mapping visualization, Log-scaled plot, CutMin and CutMax features, Hints
+@node Mapping visualization, Making histogram, STFA sample, Hints
 @subsection Mapping visualization
 
 Sometime ago I worked with mapping and have a question about its visualization. Let me remember you that mapping is some transformation rule for one set of number to another one. The 1d mapping is just an ordinary function -- it takes a number and transforms it to another one. The 2d mapping (which I used) is a pair of functions which take 2 numbers and transform them to another 2 ones. Except general plots (like @code{SurfC}, @code{SurfA}) there is a special plot -- Arnold diagram. It shows the area which is the result of mapping of some initial area (usually square).
 
 I tried to make such plot in @code{Map}. It shows the set of points or set of faces, which final position is the result of mapping. At this, the color gives information about their initial position and the height describes Jacobian value of the transformation. Unfortunately, it looks good only for the simplest mapping but for the  real multivalent quasi-chaotic mapping it produces a confusion. So, use it if you like :).
 
-@c ------------------------------------------------------------------
-@node Log-scaled plot, ``Templates'', Mapping visualization, Hints
-@subsection Log-scaled plot
+The sample code for mapping visualization is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData a(50, 40), b(50, 40);
+  gr->Puts(mglPoint(0, 0), "\\to", ":C", -1.4);
+  gr->SetRanges(-1,1,-1,1,-2,2);
 
-Log-scaled plot can be drawn by 2 steps. First, one should change the scale of axis by call @code{SetFunc("lg(x)", "lg(y)");} (in this example, x- and y-axis will be log-scaled). Second, one should set logarithmic scale for axis ticks by changing variables: @code{SetTicks('x',0); SetTicks('y',0);}. Finally, one should check (or change) the axis ranges and origin so that their values to be positive. For example of log-log plot @pxref{Log-log sample}.
+  gr->SubPlot(2, 1, 0);
+  gr->Fill(a,"x");  gr->Fill(b,"y");
+  gr->Puts(mglPoint(0, 1.1), "\\{x, y\\}", ":C", -2);   gr->Box();
+  gr->Map(a, b, "brgk");
 
-@c ------------------------------------------------------------------
-@node ``Templates'', Nonlinear fitting hints, Log-scaled plot, Hints
-@subsection ``Templates''
+  gr->SubPlot(2, 1, 1);
+  gr->Fill(a,"(x^3+y^3)/2");  gr->Fill(b,"(x-y)/2");
+  gr->Puts(mglPoint(0, 1.1), "\\{\\frac{x^3+y^3}{2}, \\frac{x-y}{2}\\}", ":C", -2);
+  gr->Box();
+  gr->Map(a, b, "brgk");
+  return 0;
+}
+@end verbatim
 
-As I have noted before, the change of settings will influence only for the further plotting commands. This allows one to create template function which will contain settings and primitive drawing for often used plots. Correspondingly one may call this template-function for drawing simplification.
+@fig{png/map, Example of Map().}
 
-For example, let one has a set of points (experimental or numerical) and wants to compare it with theoretical law (for example, with exponent law @math{\exp(-x/2), x \in [0, 20]}). The template-function for this task is:
-@verbatim
-    void template(mglGraph *gr)
-    {
-        mglData  law(100);      // create the law
-        law.Modify("exp(-10*x)");
-        gr->Axis(mglPoint(0,0.0001), mglPoint(20,1), mglPoint(0,0.0001));
-        gr->SetFunc(0,"lg(y)",0);   gr->dy = 0;
-        gr->Plot(law,"r2");
-        gr->Text(mglPoint(10,0.2),"Theoretical law: e^x","rL");
-        gr->Label('x',"x val."); gr->Label('y',"y val.");
-        gr->Axis(); gr->Grid("xy","g;"); gr->Box();
-    }
-@end verbatim
-At this, one will only write a few lines for data drawing:
+@c ------------------------------------------------------------------
+@node Making histogram, Nonlinear fitting sample, Mapping visualization, Hints
+@subsection Making histogram
+
+Using the @code{Hist} function(s) for making regular distributions is one of useful fast methods to process and plot irregular data. @code{Hist} can be used to find some momentum of set of points by specifying weight function. It is possible to create not only 1D distributions but also 2D and 3D ones. Below I place the simplest sample code which demonstrate @code{Hist} usage:
 @verbatim
-    template(gr);     // apply settings and default drawing from template
-    mglData dat("fname.dat"); // load the data
-    // and draw it (suppose that data file have 2 columns)
-    gr->Plot(dat.SubData(0),dat.SubData(1),"bx ");
+int sample(mglGraph *gr)
+{
+  mglData a(50, 40), b(50, 40);
+  gr->Puts(mglPoint(0, 0), "\\to", ":C", -1.4);
+  gr->SetRanges(-1,1,-1,1,-2,2);
+
+  gr->SubPlot(2, 1, 0);
+  gr->Fill(a,"x");  gr->Fill(b,"y");
+  gr->Puts(mglPoint(0, 1.1), "\\{x, y\\}", ":C", -2);   gr->Box();
+  gr->Map(a, b, "brgk");
+
+  gr->SubPlot(2, 1, 1);
+  gr->Fill(a,"(x^3+y^3)/2");  gr->Fill(b,"(x-y)/2");
+  gr->Puts(mglPoint(0, 1.1), "\\{\\frac{x^3+y^3}{2}, \\frac{x-y}{2}\\}", ":C", -2);
+  gr->Box();
+  gr->Map(a, b, "brgk");
+  return 0;
+}
 @end verbatim
-A template-function can also contain settings for font, transparency, lightning, color scheme and so on.
+
+@fig{png/hist, Example of Hist().}
+
 
 @c ------------------------------------------------------------------
-@node Nonlinear fitting hints, PDE solving hints, ``Templates'', Hints
+@node Nonlinear fitting sample, PDE solving hints, Making histogram, Hints
 @subsection Nonlinear fitting hints
 
-Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example (@pxref{Fitting sample}). First, let us use sin function with some random noise:
+Nonlinear fitting is rather simple. All that you need is the data to fit, the approximation formula and the list of coefficients to fit (better with its initial guess values). Let me demonstrate it on the following simple example. First, let us use sin function with some random noise:
 @verbatim
-    mglData rnd(100), idl(50); //data to be fitted and ideal data
-    rnd.Modify("0.4*rnd+0.1+sin(4*pi*x)");
-    idl.Modify("0.3+sin(4*pi*x)");
+  mglData rnd(100), in(100); //data to be fitted and ideal data
+  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  gr->Fill(in,"0.3+sin(2*pi*x)");
 @end verbatim
 and plot it to see that data we will fit
 @verbatim
-    gr->Axis(mglPoint(-1,-2), mglPoint(1,2));
-    gr->Plot(rnd, ". "); gr->Plot(idl, "b");
-    gr->Box();
-    gr->Text(mglPoint(0,2.2), "initial: y = 0.3+sin(2\pi x)", "C:b", -1);
+  gr->Title("Fitting sample");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->Axis(); gr->Plot(in, "b");
+  gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
 @end verbatim
 
 The next step is the fitting itself. For that let me specify an initial values @var{ini} for coefficients @samp{abc} and do the fitting for approximation formula @samp{a+b*sin(c*x)}
 @verbatim
-    mglData res;   // The data for found formula
-    float ini[3] = {1, 1, 3};
-    gr->Fit(res, rnd, "a+b*sin(c*x)", "abc", ini);
+  float ini[3] = {1,1,3};
+  mglData Ini(3,ini);
+  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
 @end verbatim
 Now display it
 @verbatim
-    gr->Plot(res, "r");
-    gr->Text(mglPoint(-1,-1.3), "fitted:", "L:r", -1);
-    gr->PutsFit(mglPoint(0,-1.8), "y = ", "C:r", -1);
+  gr->Plot(res, "r");
+  gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
+  gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
 @end verbatim
 
 NOTE! the fitting results may have strong dependence on initial values for coefficients due to algorithm features. The problem is that in general case there are several local "optimums" for coefficients and the program returns only first found one! There are no guaranties that it will be the best. Try for example to set @code{ini[3] = @{0, 0, 0@}} in the code above.
 
+The full sample code for nonlinear fitting is:
+@verbatim
+int sample(mglGraph *gr)
+{
+  mglData rnd(100), in(100);
+  gr->Fill(rnd,"0.4*rnd+0.1+sin(2*pi*x)");
+  gr->Fill(in,"0.3+sin(2*pi*x)");
+  float ini[3] = {1,1,3};
+  mglData Ini(3,ini);
+
+  mglData res = gr->Fit(rnd, "a+b*sin(c*x)", "abc", Ini);
+
+  gr->Title("Fitting sample");
+  gr->SetRange('y',-2,2); gr->Box();  gr->Plot(rnd, ". ");
+  gr->Axis();   gr->Plot(res, "r"); gr->Plot(in, "b");
+  gr->Puts(mglPoint(-0.9, -1.3), "fitted:", "r:L");
+  gr->PutsFit(mglPoint(0, -1.8), "y = ", "r");
+  gr->Puts(mglPoint(0, 2.2), "initial: y = 0.3+sin(2\\pi x)", "b");
+  return 0;
+}
+@end verbatim
+
+@fig{png/fit, Example of nonlinear fitting.}
+
 @c ------------------------------------------------------------------
-@node PDE solving hints, MGL parser using, Nonlinear fitting hints, Hints
+@node PDE solving hints, MGL parser using, Nonlinear fitting sample, Hints
 @subsection PDE solving hints
 
-Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (@pxref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
+Solving of Partial Differential Equations (PDE, including beam tracing) and ray tracing (or finding particle trajectory) are more or less common task. So, MathGL have several functions for that. There are @code{mglRay()} for ray tracing, @code{mglPDE()} for PDE solving, @code{mglQO2d()} for beam tracing in 2D case (see @ref{Global functions}). Note, that these functions take ``Hamiltonian'' or equations as string values. And I don't plan now to allow one to use user-defined functions. There are 2 reasons: the complexity of corresponding interface; and the basic nature of used methods which are good for samples but may not good for serious scientific calculations.
 
 The ray tracing can be done by @code{mglRay()} function. Really ray tracing equation is Hamiltonian equation for 3D space. So, the function can be also used for finding a particle trajectory (i.e. solve Hamiltonian ODE) for 1D, 2D or 3D cases. The function have a set of arguments. First of all, it is Hamiltonian which defined the media (or the equation) you are planning to use. The Hamiltonian is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, time @samp{t} (for particle dynamics) and momentums @samp{p}=@math{p_x}, @samp{q}=@math{p_y}, @samp{v}=@math{p_z}. Next, you have to define the initial conditions for coordinates and momentums at @samp{t}=0 and set the integrations step (default is 0.1) and its duration (default is 10). The Runge-Kutta method of 4-th order is used for integration.
 @verbatim
-    mglData r,a,re(128),im(128);
-    r = mglRay("p^2+q^2-x-1", mglPoint(-0.7, -1), mglPoint(0, 0.5));
-    gr->Plot(r.SubData(0), r.SubData(1));
+  const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
+  mglData r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
 @end verbatim
 This example calculate the reflection from linear layer (media with Hamiltonian @samp{p^2+q^2-x-1}=@math{p_x^2+p_y^2-x-1}). This is parabolic curve. The resulting array have 7 columns which contain data for @{x,y,z,p,q,v,t@}.
 
 The solution of PDE is a bit more complicated. As previous you have to specify the equation as pseudo-differential operator @math{\hat H(x, \nabla)} which is called sometime as ``Hamiltonian'' (for example, in beam tracing). As previously, it is defined by string which may depend on coordinates @samp{x}, @samp{y}, @samp{z} (but not time!), momentums @samp{p}=@math{(d/dx)/i k_0}, @samp{q}=@math{(d/dy)/i k_0} and field amplitude @samp{u}=@math{|u|}. The evolutionary coordinate is @samp{z} in all cases. So that, the equation look like @math{du/dz = ik_0 H(x,y,\hat p, \hat q, |u|)[u]}. Dependence on field amplitude @samp{u}=@math{|u|} allows one to solve nonlinear problems too. For example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. Also you may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{H = Hre+i*Him}).
 
-Next step is specifing the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and paramter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
+Next step is specifying the initial conditions at @samp{z}=@code{Min.z}. The function need 2 arrays for real and for imaginary part. Note, that coordinates x,y,z are supposed to be in specified range [Min, Max]. So, the data arrays should have corresponding scales. Finally, you may set the integration step and parameter k0=@math{k_0}. Also keep in mind, that internally the 2 times large box is used (for suppressing numerical reflection from boundaries) and the equation should well defined even in this extended range.
 
-Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case. 
+Final comment is concerning the possible form of pseudo-differential operator @math{H}. At this moment, simplified form of operator @math{H} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this operator is effectively @math{H = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed for 3D case.
 
-So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this (@pxref{PDE sample}):
+So, for example let solve the equation for beam deflected from linear layer and absorbed later. The operator will have the form @samp{"p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)"} that correspond to equation @math{ik_0 \partial_z u + \Delta u + x \cdot u + i (x+z)/2 \cdot u = 0}. This is typical equation for Electron Cyclotron (EC) absorption in magnetized plasmas. For initial conditions let me select the beam with plane phase front @math{exp(-48*(x+0.7)^2)}. The corresponding code looks like this:
 @verbatim
-    mglData a,re(128),im(128);
-    re.Fill("exp(-48*(x+0.7)^2)", gr->Min, gr->Max);
-    a = mglPDE("p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)", re, im,
-                gr->Min, gr->Max, 0.01, 30);
-    a.Transpose("yxz");
-    gr->CAxis(0, 1);
-    gr->Dens(a,"wyrRk");
+int sample(mglGraph *gr)
+{
+  mglData a,re(128),im(128);
+  gr->Fill(re,"exp(-48*(x+0.7)^2)");
+  a = gr->PDE("p^2+q^2-x-1+i*0.5*(z+x)*(z>-x)", re, im, 0.01, 30);
+  a.Transpose("yxz");
+  gr->SubPlot(1,1,0,"<_"); gr->Title("PDE solver");
+  gr->SetRange('c',0,1);  gr->Dens(a,"wyrRk");
+  gr->Axis(); gr->Label('x', "\\i x");  gr->Label('y', "\\i z");
+  gr->FPlot("-x", "k|");
+  gr->Puts(mglPoint(0, 0.85), "absorption: (x+z)/2 for x+z>0");
+  gr->Puts(mglPoint(0,1.1),"Equation: ik_0\\partial_zu + \\Delta u + x\\cdot u + i \\frac{x+z}{2}\\cdot u = 0");
+  return 0;
+}
 @end verbatim
 
+@fig{png/pde, Example of PDE solving.}
+
 The last example is example of beam tracing. Beam tracing equation is special kind of PDE equation written in coordinates accompanied to a ray. Generally this is the same parameters and limitation as for PDE solving but the coordinates are defined by the ray and by parameter of grid width @var{w} in direction transverse the ray. So, you don't need to specify the range of coordinates. @strong{BUT} there is limitation. The accompanied coordinates are well defined only for smooth enough rays, i.e. then the ray curvature @math{K} (which is defined as @math{1/K^2 = (|\ddot r|^2 |\dot r|^2 - (\ddot r, \dot r)^2)/|\dot r|^6}) is much large then the grid width: @math{K>>w}. So, you may receive incorrect results if this condition will be broken.
 
 You may use following code for obtaining the same solution as in previous example:
 @verbatim
-    mglData r, xx, yy, a, im(128), re(128);
-    const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
-    r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
-    // now start beam tracing
-    re.Fill("exp(-48*x^2)", gr->Min, gr->Max);
-    a = mglQO2d(ham, re, im, r, 1, 30, &xx, &yy);
-    gr->CAxis(0, 1);
-    gr->Dens(xx, yy, a, "wyrRk");
+int sample(mglGraph *gr)
+{
+  mglData r, xx, yy, a, im(128), re(128);
+  const char *ham = "p^2+q^2-x-1+i*0.5*(y+x)*(y>-x)";
+  r = mglRay(ham, mglPoint(-0.7, -1), mglPoint(0, 0.5), 0.02, 2);
+  gr->SubPlot(1,1,0,"<_"); gr->Title("Beam and ray tracing");
+  gr->Plot(r.SubData(0), r.SubData(1), "k");
+  gr->Axis(); gr->Label('x', "\\i x");  gr->Label('y', "\\i z");
+
+  // now start beam tracing
+  gr->Fill(re,"exp(-48*x^2)");
+  a = mglQO2d(ham, re, im, r, xx, yy, 1, 30);
+  gr->SetRange('c',0, 1);
+  gr->Dens(xx, yy, a, "wyrRk");
+  gr->FPlot("-x", "k|");
+  gr->Puts(mglPoint(0, 0.85), "absorption: (x+y)/2 for x+y>0");
+  gr->Puts(mglPoint(0.7, -0.05), "central ray");
+  return 0;
+}
 @end verbatim
 
+@fig{png/qo2d, Example of beam tracing.}
+
 
 @c ------------------------------------------------------------------
-@node MGL parser using, Stereo image, PDE solving hints, Hints
+@node MGL parser using, ``Templates'', PDE solving hints, Hints
 @subsection MGL parser using
 
-Sometimes you may prefer to use MGL scripts in yours code. It is simpler (especially in comparison with C/Fortran interfaces) and fast way to plot the data with annotations, labels and so on. Class @code{mglParse} (@pxref{mglParse class} parse MGL scripts in C++. It have also the corresponding interface for C/Fortran.
+Sometimes you may prefer to use MGL scripts in yours code. It is simpler (especially in comparison with C/Fortran interfaces) and provide faster way to plot the data with annotations, labels and so on. Class @code{mglParse} (@pxref{mglParse class} parse MGL scripts in C++. It have also the corresponding interface for C/Fortran.
 
-The key function here is @code{mglParse::Parse()} (or @code{mgl_parse()} for C/Fortran) which execute one command per string. At this the detailed information about the possible errors or warnings is passed as function value. Or you may execute the whole script as long string with lines separated by @samp{\n}. Functions @code{mglParse::Execute()} and @code{mgl_parse_text()} perform it. Also you may set the values of paramters @samp{$0}...@samp{$9} for the script by functions @code{mglParse::AddParam()} or @code{mgl_add_param()}, allow/disable picture resizing, check ``once'' status and so on. The usage is rather stright-forward.
+The key function here is @code{mglParse::Parse()} (or @code{mgl_parse()} for C/Fortran) which execute one command per string. At this the detailed information about the possible errors or warnings is passed as function value. Or you may execute the whole script as long string with lines separated by @samp{\n}. Functions @code{mglParse::Execute()} and @code{mgl_parse_text()} perform it. Also you may set the values of parameters @samp{$0}...@samp{$9} for the script by functions @code{mglParse::AddParam()} or @code{mgl_add_param()}, allow/disable picture resizing, check ``once'' status and so on. The usage is rather straight-forward.
 
-The only non-obvious thing is data transition between script and yours program. There are 2 stages: add or find variable; and set data to variable. In C++ you may use functions @code{mglParse::AddVar()} and @code{mglParse::FindVar()} which return pointer to @code{mglVar} structure. This structure contain data itself, the variable name and callback function which will be called if variable destroied. Last feature allows you to control the presence of the variable and, for example, close a window with data if this variable is destroyed. In C/Fortran the corresponding functions are @code{mgl_add_var()}, @code{mgl_find_var()}. But these functions return the data array only. Note, you @strong{must not delete or free} the data obtained from these functions!
+The only non-obvious thing is data transition between script and yours program. There are 2 stages: add or find variable; and set data to variable. In C++ you may use functions @code{mglParse::AddVar()} and @code{mglParse::FindVar()} which return pointer to @code{mglData}. In C/Fortran the corresponding functions are @code{mgl_add_var()}, @code{mgl_find_var()}. This data pointer is valid until next @code{Parse()} or @code{Execute()} call. Note, you @strong{must not delete or free} the data obtained from these functions!
 
 So, some simple example at the end. Here I define a data array, create variable, put data into it and plot it. The C++ code looks like this:
 @verbatim
-    float a[100];   // let a_i = sin(4*pi*x), x=0...1
-    for(int i=0;i<100;i++)  a[i]=sin(4*M_PI*i/99);
-    mglParse *parser = new mglParse;
-    mglData &d = (parser->AddVar("dat"))->d;
-    d.Set(a,100); // set data to variable
-    parser->Execute(gr, "plot dat; xrange 0 1\nbox\naxis");
-    // you may break script at any line do something 
-    // and continue after that
-    parser->Execute(gr, "xlabel 'x'\nylabel 'y'");
-    // also you may use cycles or conditions in script
-    parser->Execute(gr, "for $0 -1 1 0.1\nline 0 0 -1 $0 'r'\nnext");
-    gr->WritePNG("test.png");   // don't forgot to save picture
+int sample(mglGraph *gr)
+{
+  gr->Title("MGL parser sample");
+  float a[100];   // let a_i = sin(4*pi*x), x=0...1
+  for(int i=0;i<100;i++)a[i]=sin(4*M_PI*i/99);
+  mglParse *parser = new mglParse;
+  mglData *d = parser->AddVar("dat");
+  d->Set(a,100); // set data to variable
+  parser->Execute(gr, "plot dat; xrange 0 1\nbox\naxis");
+  // you may break script at any line do something
+  // and continue after that
+  parser->Execute(gr, "xlabel 'x'\nylabel 'y'\nbox");
+  // also you may use cycles or conditions in script
+  parser->Execute(gr, "for $0 -1 1 0.1\nline 0 0 -1 $0 'r'\nnext");
+  delete parser;
+  return 0;
+}
 @end verbatim
 The code in C/Fortran looks practically the same:
 @verbatim
-    float a[100];   // let a_i = sin(4*pi*x), x=0...1
-    int i;
-    for(i=0;i<100;i++)  a[i]=sin(4*M_PI*i/99);
-    HMPR parser = mgl_create_parser();
-    HMDT d = mgl_add_var(parser, "dat");
-    mgl_data_set_float(d,a,100,1,1);    // set data to variable
-    mgl_parse_text(gr, parser, "plot dat; xrange 0 1\nbox\naxis");
-    // you may break script at any line do something 
-    // and continue after that
-    mgl_parse_text(gr, parser, "xlabel 'x'\nylabel 'y'");
-    // also you may use cycles or conditions in script
-    mgl_parse_text(gr, parser, "for $0 -1 1 0.1\nline 0 0 -1 $0 'r'\nnext");
-    mgl_write_png(gr, "test.png", "");  // don't forgot to save picture
+int sample(HMGL gr)
+{
+  mgl_title(gr, "MGL parser sample")
+  float a[100];   // let a_i = sin(4*pi*x), x=0...1
+  int i;
+  for(i=0;i<100;i++)  a[i]=sin(4*M_PI*i/99);
+  HMPR parser = mgl_create_parser();
+  HMDT d = mgl_add_var(parser, "dat");
+  mgl_data_set_float(d,a,100,1,1);    // set data to variable
+  mgl_parse_text(gr, parser, "plot dat; xrange 0 1\nbox\naxis");
+  // you may break script at any line do something
+  // and continue after that
+  mgl_parse_text(gr, parser, "xlabel 'x'\nylabel 'y'");
+  // also you may use cycles or conditions in script
+  mgl_parse_text(gr, parser, "for $0 -1 1 0.1\nline 0 0 -1 $0 'r'\nnext");
+  mgl_write_png(gr, "test.png", "");  // don't forgot to save picture
+  return 0;
+}
+@end verbatim
+
+@fig{png/parser, Example of MGL script parsing.}
+
+@c ------------------------------------------------------------------
+@node ``Templates'', Nonlinear fitting sample, MGL parser using, Hints
+@subsection ``Templates''
+
+As I have noted before, the change of settings will influence only for the further plotting commands. This allows one to create ``template'' function which will contain settings and primitive drawing for often used plots. Correspondingly one may call this template-function for drawing simplification.
+
+For example, let one has a set of points (experimental or numerical) and wants to compare it with theoretical law (for example, with exponent law @math{\exp(-x/2), x \in [0, 20]}). The template-function for this task is:
+@verbatim
+void template(mglGraph *gr)
+{
+  mglData  law(100);      // create the law
+  law.Modify("exp(-10*x)");
+  gr->SetRanges(0,20, 0.0001,1);
+  gr->SetFunc(0,"lg(y)",0);
+  gr->Plot(law,"r2");
+  gr->Puts(mglPoint(10,0.2),"Theoretical law: e^x","r:L");
+  gr->Label('x',"x val."); gr->Label('y',"y val.");
+  gr->Axis(); gr->Grid("xy","g;"); gr->Box();
+}
+@end verbatim
+At this, one will only write a few lines for data drawing:
+@verbatim
+  template(gr);     // apply settings and default drawing from template
+  mglData dat("fname.dat"); // load the data
+  // and draw it (suppose that data file have 2 columns)
+  gr->Plot(dat.SubData(0),dat.SubData(1),"bx ");
 @end verbatim
+A template-function can also contain settings for font, transparency, lightning, color scheme and so on.
+
+I understand that this is obvious thing for any professional programmer, but I several times receive suggestion about ``templates'' ... So, I decide to point out it here.
 
 @c ------------------------------------------------------------------
-@node Stereo image, , MGL parser using, Hints
+@node Stereo image, , ``Templates'', Hints
 @subsection Stereo image
 
-One can easily create stereo image in MathGL. Stereo image can be produced by making two subplots with slightly different rotation angles. The corresponding code looks like this (@pxref{Stereo image sample}):
+One can easily create stereo image in MathGL. Stereo image can be produced by making two subplots with slightly different rotation angles. The corresponding code looks like this:
 @verbatim
-    gr->SubPlot(2,1,0);     // left image
-    gr->Rotate(40,60+3);
-    // draw something here
-    
-    gr->SubPlot(2,1,1);     // right image
-    gr->Rotate(40,60-3);
-    // draw the same here
+int sample(mglGraph *gr)
+{
+  mglData a;  mgls_prepare2d(&a);
+  gr->Light(true);
+
+  gr->SubPlot(2,1,0); gr->Rotate(50,60+1);
+  gr->Box();  gr->Surf(a);
+
+  gr->SubPlot(2,1,1); gr->Rotate(50,60-1);
+  gr->Box();  gr->Surf(a);
+  return 0;
+}
 @end verbatim
 
+@fig{png/stereo, Example of stereo image.}
+
+@node FAQ, , Hints, Examples
+@section FAQ
+
+@table @strong
+@item The plot does not appear
+Check that points of the plot lie  inside the bounding box and resize the bounding box using @code{Axis()} function. Check that the data have correct dimensions for selected type of plot. Be sure that  @code{Finish()} is called after the plotting functions (or be sure that the plot is saved to a file). Sometimes the light reflection from flat surfaces (like, @code{Dens()}) can look as if the plot were absent.
+
+@item I can not find some special kind of plot.
+Most ``new'' types of plots can be created by using the existing drawing functions. For example, the surface of curve rotation can be created by a special function @code{Torus()}, or as a parametrically specified surface by @code{Surf()}. See also, @ref{Hints}. If you can not find a specific type of plot, please e-mail me and this plot will appear in the next version of MathGL library.
+
+@item Should I know some graphical libraries (like OpenGL) before using the MathGL library?
+No. The MathGL library is self-contained and does not require the knowledge of external libraries.
+
+@item In which language is the library written? For which languages does it have an interface?
+The core of the MathGL library is written in C++. But there are interfaces for: pure C, Fortran, Pascal, Forth, and its own command language MGL. Also there is a large set of interpreted languages, which are supported (Python, Java,  ALLEGROCL, CHICKEN, Lisp, CFFI, C#, Guile, Lua, Modula 3, Mzscheme, Ocaml, Octave, Perl, PHP, Pike, R, Ruby, Tcl). These interfaces are written using SWIG (both pure C functions and classes) but only the interface for Python and Octave is included in the autoconf/automake script. The reason is that I don't know any other interpreted languages :(. Note that most other languages can use (link to) the pure C functions.
+
+@item How can I use MathGL with Fortran?
+You can use MathGL as is with @code{gfortran} because it uses by default the AT&T notation for external functions. For other compilers (like Visual Fortran) you have to switch on the AT&T notation manually. The AT&T notation requires that the symbol @samp{_} is added at the end of each function name, function argument(s) is passed by pointers and the string length(s) is passed at the end of the argument list. For example:
+
+@emph{C function} -- @code{void mgl_fplot(HMGL graph, const char *fy, const char *stl, int n);}
+
+@emph{AT&T function} -- @code{void mgl_fplot_(uintptr_t *graph, const char *fy, const char *stl, int *n, int ly, int ls);}
+
+@item How can I print in Russian/Spanish/Arabic/Japanese, and so on?
+The standard way is to use Unicode encoding for the text output. But the MathGL library also has interface for 8-bit (char *) strings with internal conversion to Unicode. This conversion depends on the current locale OS. You may change it by @code{setlocale()} function. For example, for Russian text in CP1251 encoding you may use @code{setlocale(LC_CTYPE, "ru_RU.cp1251");} (under MS Windows the name of locale may differ -- @code{setlocale(LC_CTYPE, "russian_russia.1251")}). I strongly recommend not to use the constant @code{LC_ALL} in the conversion. Since it also changes the number format, it may lead to mistakes in formula writing and reading of the text in data files. For example, the program will await a @samp{,} as a decimal point but the user will enter @samp{.}.
+
+@item How can I exclude a point or a region of plot from the drawing?
+There are 3 general ways. First, the point with @code{NAN} value as one of the coordinates will never be plotted. Second, special variables @var{CutMin}, @var{CutMax} or function @code{CutOff}() define the condition when the points should be omitted (see @ref{Cutting}). Last, you may change the transparency of a part of the plot by the help of functions @code{SurfA()}, @code{Surf3A()} (see @ref{Dual plotting}). In this last case the transparency is switched on smoothly.
+
+@item I use VisualStudio, CBuilder or some other compiler (not MinGW/gcc). How can I link the MathGL library?
+In version 2.0, the recommended class @code{mglGraph} (header file @code{#include <mgl/mgl.h>}) contains only @code{inline} functions and is acceptable for any compiler with the same binary files. However, if you plan to access low-level features (i.e. classes mglBase, mglCanvas and so on) then you have to recompile MathGL by yours compiler.
+
+@c @strong{Finally!} Please @emph{do not} ask me Windows-specific questions. I do not use Windows. I know nothing about Visual Basic, Visual C++, CBuiled or .NET. Please find the appropriate Usenet discussion group and ask your question there.
+
+@item How I can build MathGL under Windows?
+The simplest way is using the combination CMake+MinGW. Also you need some extra libraries like GSL, PNG, JPEG and so on. All of them can be found at @url{http://gnuwin32.sourceforge.net/packages.html}. After installing all components, just run CMake configurator and make the MathGL itself.
+
+@item How many people write this library?
+Most of the library was written by one person. This is a result of nearly a year of work (mostly in the evening and on holidays): I spent half a year to write the kernel and half a year to a year on extending, improving the library and writing documentation. This process continues now :). The autoconf/automake script was written mostly by D.Kulagin, and the export to IDTF was written mostly by M.Vidassov.
+
+@item How can I display a bitmap on the figure?
+You can import data into a @code{mglData} instance and display it by @code{Dens()} function. For example, for black-and-white bitmap you can use the code: @code{mglData bmp; bmp.Import("fname.png","wk"); gr->Dens(bmp,"wk");}.
+
+@item How can I use MathGL in Qt, FLTK, wxWidgets etc.?
+There are special classes (widgets) for these libraries: QMathGL for Qt, Fl_MathGL for FLTK and so on. If you don't find the appropriate class then you can create your own widget that displays a bitmap using mglCanvas::GetBits().
+
+@item How can I create U3D file (make 3D in PDF)?
+There are 2 steps: first you should create IDTF file, and later convert it to U3D. You can use @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=300628, U3D tools} for converting IDTF file to U3D. It needs @uref{http://libharu.org, libharu} 2.1.0 or later. For installation use @code{./bootstrap, ./configure, make, sudo make install}. It provides  IDTFConverter program for converting text files *.idtf to binary files *.u3d. The latter can be included into PDF.
+
+@item How I can change the font family?
+First, you should download new font files from @uref{http://mathgl.sourceforge.net/download.html, here} or from @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=267177, here}. Next, you should load the font files into mglGraph class instance @var{gr} by the following command: @code{gr->LoadFont(fontname,path);}. Here @var{fontname} is the base font name like @samp{STIX} and @var{path} sets the location of font files. Use @code{gr->RestoreFont();} to start using the default font.
+
+@item How can I draw tick out of a bounding box?
+Just set a negative value in @var{SetTickLen}. For example, use @code{gr->SetTickLen(-0.1);}.
+
+@item How can I prevent text rotation?
+Just use @code{SetRotatedText(false)}.
+
+@item What is @code{*.so}? What is @code{gcc}? How I can use @code{make}?
+This standard GNU tool. There is special FAQ about its usage under Windows -- @uref{http://www.mingw.org/wiki/FAQ}.
+
+@end table
+
index e88791f20822026692f6171b6b6761e2d62108d5..28ac2e495930ea7439e6cf4e94fd4a73ac6465e7 100644 (file)
@@ -70,45 +70,71 @@ supports it in developing GNU and promoting software freedom.''
 @menu
 * Overview::
 * Examples::
+* General concepts::
 * MathGL core::
 * Widget classes::
 * Data processing::
+* MGL scripts::
 * Other classes::
-* Samples::
 * TeX-like symbols::
 * Copying This Manual::
 * Index::
 @end menu
 
+@ifhtml
+@macro fig {fname,text}
+@center @image{../\fname\, 11cm, , \text\, .png}
+@end macro
+@end ifhtml
+
+@ifnothtml
+@iftex
+@macro fig {fname,text}
+@center @image{\fname\, 11cm, , \text\, .png}
+@end macro
+@end iftex
+
+@ifnottex
+@macro fig {fname,text}
+@c @center @image{\fname\, 11cm, , \text\, .png}
+@end macro
+@end ifnottex
+@end ifnothtml
+
+
 @rmacro sref {arg}
 См. раздел @ref{\arg\}, для примеров кода и графика.
 @end rmacro
-@macro tdref{nam}
+@macro tdref {nam}
 @uref{http://mathgl.sourceforge.net/pdf_u3d/\nam\.pdf, 3D pdf}
 @end macro
 
+
 @node Overview, Examples, , Top
 @include overview_ru.texi
 
-@node Examples, MathGL core, Overview, Top
+@node Examples, General concepts, Overview, Top
 @include example_ru.texi
 
-@node MathGL core, Widget classes, Examples, Top
+@node General concepts, MathGL core, Examples, Top
+@include concept_ru.texi
+
+@node MathGL core, Widget classes, General concepts, Top
 @include core_ru.texi
 
-@node Widget classes, Data handling, MathGL core, Top
+@node Widget classes, Data processing, MathGL core, Top
 @include widget_ru.texi
 
-@node Data processing, Other classes, Widget classes, Top
+@node Data processing, MGL scripts, Widget classes, Top
 @include data_ru.texi
 
-@node Other classes, Samples, Data handling, Top
-@include other_ru.texi
+@node MGL scripts, Other classes, Data processing, Top
+@include parse_ru.texi
 
-@node Samples, TeX-like symbols, Other classes, Top
-@include samples_ru.texi
+@node Other classes, TeX-like symbols, MGL scripts, Top
+@include other_ru.texi
 
-@node TeX-like symbols, Copying This Manual, Samples, Top
+@node TeX-like symbols, Copying This Manual, Other classes, Top
 @appendix Символы TeX
 @include appendix_ru.texi
 
index ddef55e6c822c600e81c8f9299e47ab77d86709b..144079834065e9c31308e7a0e1a8139fee9e98c6 100644 (file)
 @c ------------------------------------------------------------------
 @chapter Other classes
 
+There are only 5 end-user classes: @code{mglGraph} (see @ref{MathGL core}), @code{mglWindow} and @code{mglGLUT} (see @ref{Widget classes}), @code{mglData} (see @ref{Data processing}), @code{mglParse} (see @ref{MGL scripts}). Exactly these classes I recommend to use in most of user programs. All methods in all of these classes are inline and have exact C/Fortran analogue functions. This give compiler independent binary libraries for MathGL.
+
+However, sometimes you may need to extend MathGL by writing yours own plotting functions or handling yours own data structures. In these cases you may need to use low-level API. This chapter describes it.
+
+@fig{classes, Class diagram for MathGL}
+
+The internal structure of MathGL is rather complicated. There are C++ classes @code{mglBase}, @code{mglCanvas}, ... for drawing primitives and positioning the plot (blue ones in the figure). There is a layer of C functions, which include interface for most important methods of these classes. Also most of plotting functions are implemented as C functions. After it, there are ``inline'' front-end classes which are created for user convenience (yellow ones in the figure). Also there are 2 classes which are widgets for FLTK and Qt libraries (green ones in the figure).
+
+Below I show how this internal classes can be used.
+
 @menu
-* mglParse class::
-* mglFormula class::
+* mglBase class::
+* mglDataA class::
+* mglColor class::              
+* mglPoint class::              
 * mglFont class::
-* mglColor class::
-* mglPoint class::
-* mglVar class::
-* mglCommand class::
-* mglArg class::
 @end menu
 
+
 @c ------------------------------------------------------------------
-@node mglParse class, mglFormula class, , Other classes
-@section mglParse class
-@cindex mglParse
+@node mglBase class, mglDataA class, , Other classes
+@subsection Define new kind of plot (mglBase class)
+
+Basically most of new kinds of plot can be created using just MathGL primitives (see @ref{Primitives}). However the usage of @code{mglBase} methods can give you higher speed of drawing and better control of plot settings. 
+
+All plotting functions should use a pointer to @code{mglBase} class (or @code{HMGL} type in C functions) due to compatibility issues. Exactly such type of pointers are used in front-end classes (@code{mglGraph, mglWindow}) and in widgets (@code{QMathGL, Fl_MathGL}).
+
+MathGL tries to remember all vertexes and all primitives and plot creation stage, and to use them for making final picture by demand. Basically for making plot, you need to add vertexes by @code{AddPnt()} function, which return index for new vertex, and call one of primitive drawing function (like @code{mark_plot(), arrow_plot(), line_plot(), trig_plot(), quad_plot(), text_plot()}), using vertex indexes as argument(s). @code{AddPnt()} function use 2 float numbers for color specification. First one is positioning in textures -- integer part is texture index, fractional part is relative coordinate in the texture. Second number is like a transparency of plot (or second coordinate in the 2D texture).
+
+I don't want to put here detailed description of @code{mglBase} class. It was rather well documented in @code{mgl/base.h} file. I just show and example of its usage on the base of circle drawing.
+
+First, we should prototype new function @code{circle()} as C function.
+@verbatim
+#ifdef __cplusplus
+extern "C" {
+#endif
+void circle(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt);
+#ifdef __cplusplus
+}
+#endif
+@end verbatim
+This is done for generating compiler independent binary. Because only C-functions have standard naming mechanism, the same for any compilers.
+
+Now, we create a C++ file and put the code of function. I'll write it line by line and try to comment all important points.
+@verbatim
+void circle(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt)
+{
+@end verbatim
+First, we need to check all input arguments and send warnings if something is wrong. In our case it is negative value of @var{r} argument. We just send warning, since it is not critical situation -- other plot still can be drawn.
+@verbatim
+  if(r<=0)  { gr->SetWarn(mglWarnNeg,"Circle"); return; }
+@end verbatim
+Next step is creating a group. Group keep some general setting for plot (like options) and useful for export in 3d files.
+@verbatim
+  static int cgid=1;  gr->StartGroup("Circle",cgid++);
+@end verbatim
+Now let apply options. Options are rather useful things, generally, which allow one easily redefine axis range(s), transparency and other settings (see @ref{Command options}).
+@verbatim
+  gr->SaveState(opt);
+@end verbatim
+I use global setting for determining the number of points in circle approximation. Note, that user can change @code{MeshNum} by options easily.
+@verbatim
+  const int n = gr->MeshNum>1?gr->MeshNum : 41;
+@end verbatim
+Let try to determine plot specific flags. MathGL functions expect that most of flags will be sent in string. In our case it is symbol @samp{@@} which set to draw filled circle instead of border only (last will be default). Note, you have to handle @code{NULL} as string pointer.
+@verbatim
+  bool fill = stl && strchr(stl,'@');
+@end verbatim
+Now, time for coloring. I use palette mechanism because circle have few colors: one for filling and another for border. @code{SetPenPal()} function parse input string and write resulting texture index in @var{pal}. Function return the character for marker, which can be specified in string @var{str}. Marker will be plotted at the center of circle. I'll show on next sample how you can use color schemes (smooth colors) too.
+@verbatim
+  long pal=0;
+  char mk=gr->SetPenPal(stl,&pal);
+@end verbatim
+Next step, is determining colors for filling and for border. First one for filling.
+@verbatim
+  float c=gr->NextColor(pal), d;
+@end verbatim
+Second one for border. I use black color (call @code{gr->AddTexture('k')}) if second color is not specified.
+@verbatim
+  float k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k');
+@end verbatim
+If user want draw only border (@code{fill=false}) then I use first color for border.
+@verbatim
+  if(!fill) k=c;
+@end verbatim
+Now we should reserve space for vertexes. This functions need @code{n} for border, @code{n+1} for filling and @code{1} for marker. So, maximal number of vertexes is @code{2*n+2}. Note, that such reservation is not required for normal work but can sufficiently speed up the plotting.
+@verbatim
+  gr->Reserve(2*n+2);
+@end verbatim
+We've done with setup and ready to start drawing. First, we need to add vertex(es). Let define NAN as normals, since I don't want handle lighting for this plot,
+@verbatim
+  mglPoint q(NAN,NAN);
+@end verbatim
+and start adding vertexes. First one for central point of filling. I use @code{-1} if I don't need this point. The arguments of @code{AddPnt()} function is: @code{mglPoint(x,y,z)} -- coordinate of vertex, @code{c} -- vertex color, @code{q} -- normal at vertex, @code{-1} -- vertex transparency (@code{-1} for default), @code{3} bitwise flag which show that coordinates will be scaled (@code{0x1}) and will not be cutted (@code{0x2}).
+@verbatim
+  long n0,n1,n2,m1,m2,i;
+  n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1;
+@end verbatim
+Similar for marker, but we use different color @var{k}.
+@verbatim
+  n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1;
+@end verbatim
+Draw marker.
+@verbatim
+  if(mk)  gr->mark_plot(n2,mk);
+@end verbatim
+Time for drawing circle itself. I use @code{-1} for @var{m1}, @var{n1} as sign that primitives shouldn't be drawn for first point @code{i=0}.
+@verbatim
+  for(i=0,m1=n1=-1;i<n;i++)
+  {
+@end verbatim
+Each function should check @code{Stop} variable and return if it is non-zero. It is done for interrupting drawing for system which don't support multi-threading.
+@verbatim
+    if(gr->Stop)  return;
+@end verbatim
+Let find coordinates of vertex.
+@verbatim
+    float t = i*2*M_PI/(n-1.);
+    mglPoint p(x+r*cos(t), y+r*sin(t), z);
+@end verbatim
+Save previous vertex and add next one
+@verbatim
+    n2 = n1;  n1 = gr->AddPnt(p,c,q,-1,3);
+@end verbatim
+and copy it for border but with different color. Such copying is much faster than adding new vertex using @code{AddPnt()}.
+@verbatim
+    m2 = m1;  m1 = gr->CopyNtoC(n1,k);
+@end verbatim
+Now draw triangle for filling internal part
+@verbatim
+    if(fill)  gr->trig_plot(n0,n1,n2);
+@end verbatim
+and draw line for border.
+@verbatim
+    gr->line_plot(m1,m2);
+  }
+@end verbatim
+Drawing is done. Let close group and return.
+@verbatim
+  gr->EndGroup();
+}
+@end verbatim
+
+Another sample I want to show is exactly the same function but with smooth coloring using color scheme. So, I'll add comments only in the place of difference.
+
+@verbatim
+void circle_cs(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt)
+{
+@end verbatim
+In this case let allow negative radius too. Formally it is not the problem for plotting (formulas the same) and this allow us to handle all color range.
+@verbatim
+//if(r<=0)  { gr->SetWarn(mglWarnNeg,"Circle"); return; }
+
+  static int cgid=1;  gr->StartGroup("CircleCS",cgid++);
+  gr->SaveState(opt);
+  const int n = gr->MeshNum>1?gr->MeshNum : 41;
+  bool fill = stl && strchr(stl,'@');
+@end verbatim
+Here is main difference. We need to create texture for color scheme specified by user
+@verbatim
+  long ss = gr->AddTexture(stl);
+@end verbatim
+But we need also get marker and color for it (if filling is enabled). Let suppose that marker and color is specified after @samp{:}. This is standard delimiter which stop color scheme entering. So, just lets find it and use for setting pen.
+@verbatim
+  const char *pen=0;
+  if(stl) pen = strchr(stl,':');
+  if(pen) pen++;
+@end verbatim
+The substring is placed in @var{pen} and it will be used as line style.
+@verbatim
+  long pal=0;
+  char mk=gr->SetPenPal(pen,&pal);
+@end verbatim
+Next step, is determining colors for filling and for border. First one for filling.
+@verbatim
+  float c=gr->GetC(ss,r);
+@end verbatim
+Second one for border.
+@verbatim
+  float k=gr->NextColor(pal);
+@end verbatim
+The rest part is the same as in previous function.
+@verbatim
+  if(!fill) k=c;
+
+  gr->Reserve(2*n+2);
+  mglPoint q(NAN,NAN);
+  long n0,n1,n2,m1,m2,i;
+  n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1;
+  n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1;
+  if(mk)  gr->mark_plot(n2,mk);
+  for(i=0,m1=n1=-1;i<n;i++)
+  {
+    if(gr->Stop)  return;
+    float t = i*2*M_PI/(n-1.);
+    mglPoint p(x+r*cos(t), y+r*sin(t), z);
+    n2 = n1;  n1 = gr->AddPnt(p,c,q,-1,3);
+    m2 = m1;  m1 = gr->CopyNtoC(n1,k);
+    if(fill)  gr->trig_plot(n0,n1,n2);
+    gr->line_plot(m1,m2);
+  }
+  gr->EndGroup();
+}
+@end verbatim
+
+The last thing which we can do is derive our own class with new plotting functions. Good idea is to derive it from @code{mglGraph} (if you don't need extended window), or from @code{mglWindow} (if you need to extend window). So, in our case it will be
+@verbatim
+class MyGraph : public mglGraph
+{
+public:
+  inline void Circle(mglPoint p, float r, const char *stl="", const char *opt="")
+  { circle(p.x,p.y,p.z, r, stl, opt); }
+  inline void CircleCS(mglPoint p, float r, const char *stl="", const char *opt="")
+  { circle_cs(p.x,p.y,p.z, r, stl, opt); }
+};
+@end verbatim
+Note, that I use @code{inline} modifier for using the same binary code with different compilers. 
+
+So, the complete sample will be
+@verbatim
+#include <mgl/mgl.h>
+//---------------------------------------------------------
+#ifdef __cplusplus
+extern "C" {
+#endif
+void circle(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt);
+void circle_cs(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt);
+#ifdef __cplusplus
+}
+#endif
+//---------------------------------------------------------
+class MyGraph : public mglGraph
+{
+public:
+  inline void CircleCF(mglPoint p, float r, const char *stl="", const char *opt="")
+  { circle(p.x,p.y,p.z, r, stl, opt); }
+  inline void CircleCS(mglPoint p, float r, const char *stl="", const char *opt="")
+  { circle_cs(p.x,p.y,p.z, r, stl, opt); }
+};
+//---------------------------------------------------------
+void circle(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt)
+{
+  if(r<=0)  { gr->SetWarn(mglWarnNeg,"Circle"); return; }
+  static int cgid=1;  gr->StartGroup("Circle",cgid++);
+  gr->SaveState(opt);
+  const int n = gr->MeshNum>1?gr->MeshNum : 41;
+  bool fill = stl && strchr(stl,'@');
+  long pal=0;
+  char mk=gr->SetPenPal(stl,&pal);
+  float c=gr->NextColor(pal), d;
+  float k=(gr->GetNumPal(pal)>1)?gr->NextColor(pal):gr->AddTexture('k');
+  if(!fill) k=c;
+  gr->Reserve(2*n+2);
+  mglPoint q(NAN,NAN);
+  long n0,n1,n2,m1,m2,i;
+  n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1;
+  n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1;
+  if(mk)  gr->mark_plot(n2,mk);
+  for(i=0,m1=n1=-1;i<n;i++)
+  {
+    if(gr->Stop)  return;
+    float t = i*2*M_PI/(n-1.);
+    mglPoint p(x+r*cos(t), y+r*sin(t), z);
+    n2 = n1;  n1 = gr->AddPnt(p,c,q,-1,3);
+    m2 = m1;  m1 = gr->CopyNtoC(n1,k);
+    if(fill)  gr->trig_plot(n0,n1,n2);
+    gr->line_plot(m1,m2);
+  }
+  gr->EndGroup();
+}
+//---------------------------------------------------------
+void circle_cs(HMGL gr, float x, float y, float z, float r, const char *stl, const char *opt)
+{
+  static int cgid=1;  gr->StartGroup("CircleCS",cgid++);
+  gr->SaveState(opt);
+  const int n = gr->MeshNum>1?gr->MeshNum : 41;
+  bool fill = stl && strchr(stl,'@');
+  long ss = gr->AddTexture(stl);
+  const char *pen=0;
+  if(stl) pen = strchr(stl,':');
+  if(pen) pen++;
+  long pal=0;
+  char mk=gr->SetPenPal(pen,&pal);
+  float c=gr->GetC(ss,r);
+  float k=gr->NextColor(pal);
+  if(!fill) k=c;
+
+  gr->Reserve(2*n+2);
+  mglPoint q(NAN,NAN);
+  long n0,n1,n2,m1,m2,i;
+  n0 = fill ? gr->AddPnt(mglPoint(x,y,z),c,q,-1,3):-1;
+  n2 = mk ? gr->AddPnt(mglPoint(x,y,z),k,q,-1,3):-1;
+  if(mk)  gr->mark_plot(n2,mk);
+  for(i=0,m1=n1=-1;i<n;i++)
+  {
+    if(gr->Stop)  return;
+    float t = i*2*M_PI/(n-1.);
+    mglPoint p(x+r*cos(t), y+r*sin(t), z);
+    n2 = n1;  n1 = gr->AddPnt(p,c,q,-1,3);
+    m2 = m1;  m1 = gr->CopyNtoC(n1,k);
+    if(fill)  gr->trig_plot(n0,n1,n2);
+    gr->line_plot(m1,m2);
+  }
+  gr->EndGroup();
+}
+//---------------------------------------------------------
+int main()
+{
+  MyGraph gr;
+  gr.Box();
+  // first let draw circles with fixed colors
+  for(int i=0;i<10;i++)
+    gr.CircleCF(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), mgl_rnd());
+  // now let draw circles with color scheme
+  for(int i=0;i<10;i++)
+    gr.CircleCS(mglPoint(2*mgl_rnd()-1, 2*mgl_rnd()-1), 2*mgl_rnd()-1);
+}
+@end verbatim
 
-Class for parsing and executing MGL script. This class is defined in @code{#include <mgl/parse.h>}.
 
-Class mglParse is the interpreter for MGL scripts (@pxref{MGL interface}). The main function of mglParse class is @code{Parse()}. Exactly this function parses and executes the script string-by-string. Also there are two subservient functions for the finding and creation of a variable. These functions can be useful for displaying values of variables (arrays) in some external program (in window, for example). The variable @var{DataList} contains full list of variables in script. Flag @var{AllowSetSize} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).
 
-Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{} mglParse (@code{bool} setsize=@code{false})
-@deftypefnx {C function} @code{HMPR} mgl_create_parser ()
-Constructor initializes all values with zero and set @var{AllowSetSize} value.
-@end deftypefn
+@c ------------------------------------------------------------------
+@node mglDataA class, mglColor class, mglBase class, Other classes
+@subsection User defined types (mglDataA class)
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{} ~mglParse ()
-@deftypefnx {C function} @code{void} mgl_delete_parser (@code{HMPR} p)
-Destructor delete parser
-@end deftypefn
+@code{mglData} class have abstract predecessor class @code{mglDataA}. Exactly the pointers to @code{mglDataA} instances are used in all plotting functions and some of data processing functions. This was done for taking possibility to define yours own class, which will handle yours own data (for example, complex numbers, or differently organized data). And this new class will be almost the same as @code{mglData} for plotting purposes.
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
-@deftypefnx {Method on @code{mglParse} (C++)} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
-@deftypefnx {C function} @code{int} mgl_parse (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
-@deftypefnx {C function} @code{int} mgl_parsew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
-Main function in the class. It parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
-@end deftypefn
+However, the most of data processing functions will be slower as if you used @code{mglData} instance. This is more or less understandable -- I don't know how data in yours particular class will be organized, and couldn't optimize the these functions generally.
 
-@deftypefn {Method on @code{mglParse} (C++)} @code{int} Export (@code{wchar_t} cpp_out@code{[1024]}, @code{mglGraph *}gr, @code{const wchar_t *}str)
-Function parses the string @var{str}, executes it by  using @var{gr} as a graphics plotter and exports it to C++ code. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Output C++ text will be placed in @var{out} variable. If string @var{str} have options (defined after ';' symbol) then the corresponding C++ texts are placed in variables @var{op1}, @var{op2}.
-@end deftypefn
+There are few virtual functions which must be provided in derived classes. This functions give:
+@itemize @bullet
+@item
+the sizes of the data (@code{GetNx}, @code{GetNy}, @code{GetNz}),
+@item
+give data value and numerical derivatives for selected cell (@code{v}, @code{dvx}, @code{dvy}, @code{dvz}),
+@item
+give maximal and minimal values (@code{Maximal}, @code{Minimal}) -- you can use provided functions (like @code{mgl_data_max} and @code{mgl_data_min}), but yours own realization can be more efficient,
+@item
+give access to all element as in single array (@code{vthr}) -- you need this only if you want using MathGL's data processing functions.
+@end itemize
+
+Let me, for example define class @code{mglComplex} which will handle complex number and draw its amplitude or phase, depending on flag @var{use_abs}:
+@verbatim
+#include <complex>
+#include <mgl/mgl.h>
+#define dual std::complex<double>
+class mglComplex : public mglDataA
+{
+public:
+  long nx;      ///< number of points in 1st dimensions ('x' dimension)
+  long ny;      ///< number of points in 2nd dimensions ('y' dimension)
+  long nz;      ///< number of points in 3d dimensions ('z' dimension)
+  dual *a;   ///< data array
+  bool use_abs; ///< flag to use abs() or arg()
+
+  inline mglComplex(long xx=1,long yy=1,long zz=1)
+  { a=0;  use_abs=true; Create(xx,yy,zz); }
+  virtual ~mglComplex()  { if(a)  delete []a; }
+
+  /// Get sizes
+  inline long GetNx() const { return nx;  }
+  inline long GetNy() const { return ny;  }
+  inline long GetNz() const { return nz;  }
+  /// Create or recreate the array with specified size and fill it by zero
+  inline void Create(long mx,long my=1,long mz=1)
+  { nx=mx;  ny=my;  nz=mz;  if(a) delete []a;
+  a = new dual[nx*ny*nz]; }
+  /// Get maximal value of the data
+  inline float Maximal() const  { return mgl_data_max(this);  }
+  /// Get minimal value of the data
+  inline float Minimal() const  { return mgl_data_min(this);  }
+
+protected:
+  inline mreal v(long i,long j=0,long k=0) const
+  { return use_abs ? abs(a[i+nx*(j+ny*k)]) : arg(a[i+nx*(j+ny*k)]);  }
+  inline mreal vthr(long i) const
+  { return use_abs ? abs(a[i]) : arg(a[i]);  }
+  inline mreal dvx(long i,long j=0,long k=0) const
+  { register long i0=i+nx*(j+ny*k);
+    std::complex<double> res=i>0? (i<nx-1? (a[i0+1]-a[i0-1])/2.:a[i0]-a[i0-1]) : a[i0+1]-a[i0];
+    return use_abs? abs(res) : arg(res);  }
+  inline mreal dvy(long i,long j=0,long k=0) const
+  { register long i0=i+nx*(j+ny*k);
+    std::complex<double> res=j>0? (j<ny-1? (a[i0+nx]-a[i0-nx])/2.:a[i0]-a[i0-nx]) : a[i0+nx]-a[i0];
+    return use_abs? abs(res) : arg(res);  }
+  inline mreal dvz(long i,long j=0,long k=0) const
+  { register long i0=i+nx*(j+ny*k), n=nx*ny;
+    std::complex<double> res=k>0? (k<nz-1? (a[i0+n]-a[i0-n])/2.:a[i0]-a[i0-n]) : a[i0+n]-a[i0];
+    return use_abs? abs(res) : arg(res);  }
+};
+int main()
+{
+  mglComplex dat(20);
+  for(long i=0;i<20;i++)
+    dat.a[i] = 3*exp(-0.05*(i-10)*(i-10))*dual(cos(M_PI*i*0.3), sin(M_PI*i*0.3));
+  mglGraph gr;
+  gr.SetRange('y', -M_PI, M_PI);  gr.Box();
+
+  gr.Plot(dat,"r","legend 'abs'");
+  dat.use_abs=false;
+  gr.Plot(dat,"b","legend 'arg'");
+  gr.Legend();
+  gr.WritePNG("complex.png");
+  return 0;
+}
+@end verbatim
 
-@deftypefn {Method on @code{mglParse} (C++)} @code{void} Execute (@code{mglGraph *}gr, @code{FILE *}fp, @code{bool} print=@code{false})
-Function parse and execute line-by-line MGL script in file @var{fp}. If @var{print}=@code{true} then all warnings and information will be printed in stdout. Also this function support the @code{for|next} MGL commands.
-@end deftypefn
-@deftypefn {Method on @code{mglParse} (C++)} @code{void} Execute (@code{mglGraph *}gr, @code{int} num, @code{const wchar_t **}text, @code{void (*} error @code{)(int line, int kind)=NULL})
-Function parse and execute line-by-line MGL script in array @var{text}. If @var{error} is not @code{NULL} then this function will be called for all warnings, information and other messages. Also this function support the @code{for|next} MGL commands.
-@end deftypefn
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text, @code{void (*} error @code{)(int line, int kind)=NULL})
-@deftypefnx {Method on @code{mglParse} (C++)} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text, @code{void (*} error @code{)(int line, int kind)=NULL})
-@deftypefnx {C function} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text)
-@deftypefnx {C function} @code{void} mgl_parsew_text (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text)
-Function parse and execute line-by-line MGL script in string @var{text}. Lines are separated by @samp{\n} symbol as usual. If @var{error} is not @code{NULL} then this function will be called for all warnings, information and other messages. Also this function support the @code{for|next} MGL commands.
-@end deftypefn
+@c ------------------------------------------------------------------
+@node mglColor class, mglPoint class, mglDataA class, Other classes
+@section mglColor class
+@cindex mglColor
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{bool} AddParam (@code{int} n, @code{const char *}str, @code{bool} isstr=@code{true})
-@deftypefnx {Method on @code{mglParse} (C++)} @code{bool} AddParam (@code{int} n, @code{const wchar_t *}str, @code{bool} isstr=@code{true})
-@deftypefnx {C function} @code{void} mgl_add_param (@code{HMPR} p, @code{int} id, @code{const char *}val)
-@deftypefnx {C function} @code{void} mgl_add_paramw (@code{HMPR} p, @code{int} id, @code{const wchar_t *}val)
-Function set the value of @var{n}-th parameter as string @var{str} (@var{n}=0, 1 ... 9). It return @code{true} for success.
-@end deftypefn
+Structure for working with colors. This structure is defined in @code{#include <mgl/type.h>}.
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{mglVar *} FindVar (@code{const char *}name)
-@deftypefnx {Method on @code{mglParse} (C++)} @code{mglVar *} FindVar (@code{const wchar_t *}name)
-@deftypefnx {C function} @code{const HMDT} mgl_find_var  (@code{HMPR} p, @code{const char *}name)
-Function returns the pointer to variable with name @var{name} or zero if variable is absent. Use this function to put external data array to the script or get the data from the script.
-@end deftypefn
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{mglVar *} AddVar (@code{const char *}name)
-@deftypefnx {Method on @code{mglParse} (C++)} @code{mglVar *} AddVar (@code{const wchar_t *}name)
-@deftypefnx {C function} @code{const HMDT} mgl_add_var (@code{HMPR} p, @code{const char *}name)
-Function returns the pointer to variable with name @var{name}. If variable is absent then new variable is created with name @var{name}. Use this function to put external data array to the script or get the data from the script.
-@end deftypefn
+There are two ways to set the color in MathGL. First one is using of float values of red, green and blue channels for precise color definition. The second way is the using of character id. There are a set of characters specifying frequently used colors. Normally capital letter gives more dark color than lowercase one. @xref{Line styles}.
 
-@deftypefn {Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{mglVar *}v)
-@deftypefnx {Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const char *}name)
-@deftypefnx {Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const wchar_t *}name)
-Function delete the variable specified by its name or by its pointer.
-@end deftypefn
+@deftypecv {Parameter} mglColor @code{float} {r, g, b, a}
+Reg, green and blue component of color.
+@end deftypecv
 
-@deftypefn {Method on @code{mglParse} (C++, Python)} @code{inline void} RestoreOnce ()
-@deftypefnx {C function} @code{void} mgl_restore_once (@code{HMPR} p)
-Restore Once flag.
-@end deftypefn
+@deftypemethod mglColor @code{} mglColor (@code{float} R, @code{float} G, @code{float} B, @code{float} A=@code{1})
+Constructor sets the color by float values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1].
+@end deftypemethod
+@deftypemethod mglColor @code{} mglColor (@code{char} c=@code{'k'}, @code{float} bright=@code{1})
+Constructor sets the color from character id. The black color is used by default. Parameter @var{br} set additional ``lightness'' of color.
+@end deftypemethod
+@deftypemethod mglColor @code{void} Set (@code{float} R, @code{float} G, @code{float} B, @code{float} A=@code{1})
+Sets color from values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1].
+@end deftypemethod
+@deftypemethod mglColor @code{void} Set (@code{mglColor} c, @code{float} bright=@code{1})
+Sets color as ``lighted'' version of color @var{c}.
+@end deftypemethod
+@deftypemethod mglColor @code{void} Set (@code{char} p, @code{float} bright=@code{1})
+Sets color from symbolic id.
+@end deftypemethod
+@deftypemethod mglColor @code{bool} Valid ()
+Checks correctness of the color.
+@end deftypemethod
+@deftypemethod mglColor @code{float} Norm ()
+Gets maximal of spectral component.
+@end deftypemethod
+@deftypemethod mglColor @code{bool} operator== (@code{const mglColor &}c)
+@deftypemethodx mglColor @code{bool} operator!= (@code{const mglColor &}c)
+Compare with another color
+@end deftypemethod
 
-@deftypefn {Method on @code{mglParse} (Python)} @code{void} AllowSetSize (@code{bool} a)
-@deftypefnx {C function} @code{void} mgl_parser_allow_setsize (@code{HMPR} p, @code{int} a)
-Allow to parse 'setsize' command or not.
-@end deftypefn
+@deftypemethod mglColor @code{bool} operator*= (@code{float} v)
+Multiplies color components by number @var{v}.
+@end deftypemethod
 
-@deftypefn {Method on @code{mglParse} (C++)} @code{void} AddCommand (@code{mglCommand *}cmd, @code{int} num=@code{0})
-Add @var{num} commands @var{cmd} to the defined MGL commands list. Parameter @var{cmd} is array of @code{mglCommand} structures. If parameter @var{num}=0 then it will be determined automatically. At this, array @var{cmd} @strong{must have} last element with @code{name=L""}
-@end deftypefn
+@deftypemethod mglColor @code{bool} operator+= (@code{const mglColor &}c)
+Adds color @var{c} component by component.
+@end deftypemethod
+
+@deftypemethod mglColor @code{bool} operator-= (@code{const mglColor &}c)
+Subtracts color @var{c} component by component.
+@end deftypemethod
 
-@deftypecv {Option} mglParse @code{mglVar *} DataList
-List of variables defined in script.
-@end deftypecv
-@deftypecv {Option} mglParse @code{bool} AllowSetSize
-Flag which allows/forbids the command @code{setsize} in scripts.
-@end deftypecv
-@deftypecv {Option} mglParse @code{bool} Stop
-Flag which interrupt script execution.
-@end deftypecv
-@deftypecv {Option} mglParse @code{mglCommand *} Cmd
-Table (array) of recognizable MGL commands (can be changed by user). Items in the table @strong{MUST be sorted} by @var{name} field !!! Last items must have empty name (i.e. @code{L""}).
-@end deftypecv
-@deftypecv {Option} mglParse @code{wchar_t *} op1
-These strings contain command options and should be placed before the command. These variables are used for MGL->C++ (or other language) conversion.
-@end deftypecv
-@deftypecv {Option} mglParse @code{wchar_t *} op2
-These strings contain command options and should be placed after the command. These variables are used for MGL->C++ (or other language) conversion.
-@end deftypecv
+
+@deftypefn {Library Function} {mglColor} operator+ (@code{const mglColor &}a, @code{const mglColor &}b)
+Adds colors by its RGB values.
+@end deftypefn
+@deftypefn {Library Function} @code{mglColor} operator- (@code{const mglColor &}a, @code{const mglColor &}b)
+Subtracts colors by its RGB values.
+@end deftypefn
+@deftypefn {Library Function} @code{mglColor} operator* (@code{const mglColor &}a, @code{float} b)
+@deftypefnx {Library Function} @code{mglColor} operator* (@code{float} a, @code{const mglColor &}b)
+Multiplies color by number.
+@end deftypefn
+@deftypefn {Library Function} @code{mglColor} operator/ (@code{const mglColor &}a, @code{float} b)
+Divide color by number.
+@end deftypefn
+@deftypefn {Library Function} @code{mglColor} operator! (@code{const mglColor &}a)
+Return inverted color.
+@end deftypefn
 
 @c ------------------------------------------------------------------
-@node mglFormula class, mglFont class, mglParse class, Other classes
-@section mglFormula class
-@cindex mglFormula
+@node mglPoint class, mglFont class, mglColor class, Other classes
+@section mglPoint class
+@cindex mglPoint
 
-Class for evaluating of formula specified by the string. This class is defined in @code{#include <mgl/mgl_eval.h>}.
+Structure describes point in space. This structure is defined in @code{#include <mgl/type.h>}
 
-It is the fast variant of formula evaluation. At creation it will be recognized and compiled to tree-like internal code. At evaluation stage only fast calculations are performed. There is no difference between lower or upper case in formulas. If argument value lie outside the range of function definition then function returns NaN. @xref{Textual formulas}.
+@deftypecv {Parameter} mglPoint @code{float} {x, y, z, c}
+Point coordinates @{x,y,z@} and one extra value @var{c} used for amplitude, transparency and so on. By default all values are zero.
+@end deftypecv
 
-@deftypemethod mglFormula @code{} mglFormula (@code{const char *}str)
-Parses the formula @var{str} and creates formula-tree. Constructor recursively parses the formula and creates a tree-like structure containing functions and operators for fast further evaluating by @code{Calc()} or @code{CalcD()} functions.
+@deftypemethod mglPoint @code{} mglPoint (@code{float} X=@code{0}, @code{float} Y=@code{0}, @code{float} Z=@code{0}, @code{float} C=@code{0})
+Constructor sets the color by float values of Red, Green, Blue and Alpha channels. These values should be in interval [0,1].
 @end deftypemethod
-@deftypemethod mglFormula @code{float} Calc (@code{float} x, @code{float} y=@code{0}, @code{float} z=@code{0}, @code{float} u=@code{0})
-Evaluates the formula for @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}. Error code (if one) can be obtained from function @code{GetError()}.
-@end deftypemethod
-@deftypemethod mglFormula @code{float} Calc (@code{float} x, @code{float} y, @code{float} z, @code{float} u, @code{float} v, @code{float} w)
-Evaluates the formula for @code{'x'}=@var{x}, @code{'y'}=@var{y}, @code{'z'}=@var{z}, @code{'u'}=@var{u}, @code{'v'}=@var{v}, @code{'w'}=@var{w}. Error code (if one) can be obtained from function @code{GetError()}.
+
+@deftypemethod mglPoint @code{bool} IsNAN ()
+Returns @code{true} if point contain NAN values.
 @end deftypemethod
-@deftypemethod mglFormula @code{float} Calc (@code{float} var@code{['z'-'a'+1]})
-Evaluates the formula for variables in array @var{var}['z'-'a']. Error code (if one) can be obtained from function @code{GetError()}.
+@deftypemethod mglPoint @code{float} norm ()
+Returns the norm @math{\sqrt@{x^2+y^2+z^2@}} of vector.
 @end deftypemethod
-@deftypemethod mglFormula @code{float} CalcD (@code{float} var@code{['z'-'a'+1]}, @code{char} diff)
-Evaluates the formula derivation respect to @var{diff} for variables in array @var{var}['z'-'a']. Error code (if one) can be obtained from function @code{GetError()}.
+@deftypemethod mglPoint @code{void} Normalize ()
+Normalizes vector to be unit vector.
 @end deftypemethod
-@deftypemethod mglFormula @code{int} GetError ()
-Returns error code: @code{0} means no error; @code{ERR_LOG} means error in logarithm or power functions; @code{ERR_ARC} means error in inverse functions (like asin); @code{ERR_SQRT} means error in sqrt function.
+@deftypemethod mglPoint @code{float} val (@code{int} i)
+Returns point component: @var{x} for @var{i}=0, @var{y} for @var{i}=1, @var{z} for @var{i}=2, @var{c} for @var{i}=3.
 @end deftypemethod
 
+
+@deftypefn {Library Function} @code{mglPoint} operator+ (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Point of summation (summation of vectors).
+@end deftypefn
+@deftypefn {Library Function} @code{mglPoint} operator- (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Point of difference (difference of vectors).
+@end deftypefn
+@deftypefn {Library Function} @code{mglPoint} operator* (@code{float} a, @code{const mglPoint &}b)
+@deftypefnx {Library Function} @code{mglPoint} operator* (@code{const mglPoint &}a, @code{float} b)
+Multiplies (scale) points by number.
+@end deftypefn
+@deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{float} b)
+Multiplies (scale) points by number 1/b.
+@end deftypefn
+@deftypefn {Library Function} @code{float} operator* (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Scalar product of vectors.
+@end deftypefn
+
+@deftypefn {Library Function} @code{mglPoint} operator/ (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Return vector of element-by-element product.
+@end deftypefn
+
+@deftypefn {Library Function} @code{mglPoint} operator^ (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Cross-product of vectors.
+@end deftypefn
+@deftypefn {Library Function} @code{mglPoint} operator& (@code{const mglPoint &}a, @code{const mglPoint &}b)
+The part of @var{a} which is perpendicular to vector @var{b}.
+@end deftypefn
+@deftypefn {Library Function} @code{mglPoint} operator| (@code{const mglPoint &}a, @code{const mglPoint &}b)
+The part of @var{a} which is parallel to vector @var{b}.
+@end deftypefn
+
+@deftypefn {Library Function} @code{mglPoint} operator! (@code{const mglPoint &}a)
+Return vector perpendicular to vector @var{a}.
+@end deftypefn
+@deftypefn {Library Function} @code{float} mgl_norm (@code{const mglPoint &}a)
+Return the norm sqrt(|@var{a}|^2) of vector @var{a}.
+@end deftypefn
+
+@deftypefn {Library Function} @code{bool} operator== (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Return true if points are the same.
+@end deftypefn
+@deftypefn {Library Function} @code{bool} operator!= (@code{const mglPoint &}a, @code{const mglPoint &}b)
+Return true if points are different.
+@end deftypefn
+
 @c ------------------------------------------------------------------
-@node mglFont class, mglColor class, mglFormula class, Other classes
+@node mglFont class, , mglPoint class, Other classes
 @section mglFont class
 @cindex mglFont
 
-Class for working with font: load, get metrics, parse and draw strings. This class is defined in @code{#include <mgl/mgl_font.h>}.
+Class for working with font: load, get metrics, parse and draw strings. This class is defined in @code{#include <mgl/font.h>}. This class is accessible only from C++ (and only from GNU compilers in default binary files).
 
 The class is based on loading and drawing of vector Hershey font. There are two styles of specifying of the font type and aligning: by integer parameters or by string.
 
@@ -172,16 +582,16 @@ Load font from file @var{path}/@var{base} into the memory. The font may contain
 @deftypemethod mglFont @code{void} Restore ()
 Restore default font.
 @end deftypemethod
-@deftypemethod mglFont @code{void}  (@code{mglFont *} fnt)
+@deftypemethod mglFont @code{void} Copy (@code{mglFont *}fnt)
 Copy data from other font instance.
 @end deftypemethod
 @deftypemethod mglFont @code{void} Clear ()
 Clear memory by deleting the loaded font.
 @end deftypemethod
-@deftypemethod mglFont @code{inline unsigned} GetNumGlyph ()
+@deftypemethod mglFont @code{unsigned} GetNumGlyph ()
 Return the number of glyphs in the font.
 @end deftypemethod
-@deftypemethod mglFont @code{inline bool} Ready ()
+@deftypemethod mglFont @code{bool} Ready ()
 Return true if font is loaded and ready for use.
 @end deftypemethod
 
@@ -219,7 +629,7 @@ Prints Unicode text string for font specified by string.
 Gets width of Unicode text string for font specified by string.
 @end deftypemethod
 
-@deftypecv {Parameter} mglFont @code{mglGraph *} gr
+@deftypecv {Parameter} mglFont @code{HMGL} gr
 Instance of mglGraph class which is used for character drawing.
 @end deftypecv
 @deftypecv {Parameter} mglFont @code{bool} parse
@@ -248,195 +658,3 @@ Each font file can be compressed by gzip.
 
 Note: the closing contour line  is done automatically (so the last segment may be absent). For starting new contour use a point with coordinates @code{@{0x3fff, 0x3fff@}}.
 
-
-@c ------------------------------------------------------------------
-@node mglColor class, mglPoint class, mglFont class, Other classes
-@section mglColor class
-@cindex mglColor
-
-Structure for working with colors. This structure is defined in @code{#include <mgl/mgl.h>}.
-
-There are two ways to set the color in MathGL. First one is using of float values of red, green and blue channels for precise color definition. The second way is the using of character id. There are a set of characters specifying frequently used colors. Normally capital letter gives more dark color than lowercase one. @xref{Line styles}.
-
-@deftypecv {Parameter} mglVar @code{float} {r, g, b}
-Reg, green and blue component of color.
-@end deftypecv
-
-@deftypemethod mglColor @code{} mglColor (@code{float} R, @code{float} G, @code{float} B)
-Constructor sets the color by float values of Red, Green and Blue channels.
-@end deftypemethod
-@deftypemethod mglColor @code{} mglColor (@code{char} c=@code{'k'})
-Constructor sets the color from character id. The black color is used by default.
-@end deftypemethod
-@deftypemethod mglColor @code{void} Set (@code{float} R, @code{float} G, @code{float} B)
-Sets color from values of Red, Green and Blue channels. This values should be in interval [0,1].
-@end deftypemethod
-@deftypemethod mglColor @code{void} Set (@code{mglColor} c, @code{float} bright=@code{1})
-Sets color as ``lighted'' version of color @var{c}.
-@end deftypemethod
-@deftypemethod mglColor @code{void} Set (@code{char} p)
-Sets color from symbolic id.
-@end deftypemethod
-@deftypemethod mglColor @code{bool} Valid ()
-Checks correctness of the color.
-@end deftypemethod
-@deftypemethod mglColor @code{float} Norm ()
-Gets maximal of spectral component.
-@end deftypemethod
-@deftypemethod mglColor @code{bool} operator== (@code{const mglColor &}c)
-Compare with another color
-@end deftypemethod
-
-@deftypefn {Library Function} {inline mglColor} operator+ (@code{const mglColor &}a, @code{const mglColor &}b)
-Adds colors by its RGB values.
-@end deftypefn
-@deftypefn {Library Function} {inline mglColor} operator- (@code{const mglColor &}a, @code{const mglColor &}b)
-Subtracts colors by its RGB values.
-@end deftypefn
-@deftypefn {Library Function} {inline mglColor} operator* (@code{const mglColor &}a, @code{float} b)
-Multiplies color by number.
-@end deftypefn
-@deftypefn {Library Function} {inline mglColor} operator* (@code{float} a, @code{const mglColor &}b)
-Multiplies color by number.
-@end deftypefn
-@deftypefn {Library Function} {inline mglColor} operator/ (@code{const mglColor &}a, @code{float} b)
-Divide color by number.
-@end deftypefn
-@deftypefn {Library Function} {inline mglColor} operator! (@code{const mglColor &}a)
-Return inverted color.
-@end deftypefn
-
-@c ------------------------------------------------------------------
-@node mglPoint class, mglArg class, mglColor class, Other classes
-@section mglPoint class
-@cindex mglPoint
-
-Structure describes point in space. This structure is defined in @code{#include <mgl/mgl.h>}
-
-@deftypecv {Parameter} mglVar @code{float} {x, y, z}
-Point coordinates. By default all values are zero.
-@end deftypecv
-
-@deftypefn {Library Function} {inline mglPoint} operator+ (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Point of summation (summation of vectors).
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator- (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Point of difference (difference of vectors).
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator* (@code{float} a, @code{const mglPoint &}b)
-Multiplies (scale) points by number.
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator* (@code{const mglPoint &}a, @code{float} b)
-Multiplies (scale) points by number.
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator/ (@code{const mglPoint &}a, @code{float} b)
-Multiplies (scale) points by number 1/b.
-@end deftypefn
-@deftypefn {Library Function} {inline float} operator- (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Scalar product of vectors.
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator^ (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Cross-product of vectors.
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator& (@code{const mglPoint &}a, @code{const mglPoint &}b)
-The part of @var{a} which is perpendicular to vector @var{b}.
-@end deftypefn
-@deftypefn {Library Function} {inline mglPoint} operator| (@code{const mglPoint &}a, @code{const mglPoint &}b)
-The part of @var{a} which is parallel to vector @var{b}.
-@end deftypefn
-
-@deftypefn {Library Function} {inline mglPoint} operator! (@code{const mglPoint &}a)
-Return vector perpendicular to vector @var{a}.
-@end deftypefn
-@deftypefn {Library Function} {inline bool} Norm (@code{const mglPoint &}a)
-Return the norm |@var{a}|^2 of vector @var{a}.
-@end deftypefn
-
-@deftypefn {Library Function} {inline bool} operator== (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Return true if points are the same.
-@end deftypefn
-@deftypefn {Library Function} {inline bool} operator!= (@code{const mglPoint &}a, @code{const mglPoint &}b)
-Return true if points are different.
-@end deftypefn
-
-@c ------------------------------------------------------------------
-@node mglVar class, mglCommand class, mglArg class, Other classes
-@section mglVar class
-@cindex mglVar
-
-Structure describes variable of type @code{mglData} and its name in MGL script. This structure is used by @code{mglParse} and is defined in @code{#include <mgl/parse.h>}.
-
-@deftypecv {Parameter} mglVar @code{mglData} d
-Data itself
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{wchar_t} s[256]
-Data name
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{void *} o
-Pointer to external object for function @var{func}.
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{mglVar *} next
-Pointer to next instance in list
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{mglVar *} prev
-Pointer to prev instance in list
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{bool} temp
-Flag for temporar variable. Temporal variables will be destroyed after script execution.
-@end deftypecv
-@deftypecv {Parameter} mglVar @code{void (*} func @code{)(void *)}
-Callback function for destroying non-temporal variable.
-@end deftypecv
-
-@deftypemethod mglVar @code{void} MoveAfter (@code{mglVar *}var)
-Move variable after @var{var} and copy @code{func} from @code{var} (if @code{func} is not 0)
-@end deftypemethod
-
-
-@c ------------------------------------------------------------------
-@node mglCommand class, , mglVar class, Other classes
-@section mglCommand class
-@cindex mglCommand
-
-Structure describes MGL command, its name, short description, executable and export functions. The structure is used by @code{mglParse} and is defined in @code{#include <mgl/parse.h>}.
-
-@deftypecv {Parameter} mglCommand @code{const wchar_t *} name
-Name of command.
-@end deftypecv
-@deftypecv {Parameter} mglCommand @code{const wchar_t *} desc
-Short command description (can be NULL).
-@end deftypecv
-@deftypecv {Parameter} mglCommand @code{const wchar_t *} form
-Format of command arguments (can be NULL).
-@end deftypecv
-@deftypecv {Parameter} mglCommand @code{int (*} exec @code{)(mglGraph *gr, long n, mglArg *a, int k[10])const wchar_t *}
-Function for executing (plotting) the command using grapher @var{gr} and having @var{n}-th arguments @var{a}. Function must return 0 if all is OK; or 1 if arguments are wrong.
-@end deftypecv
-@deftypecv {Parameter} mglCommand @code{void (*} save @code{)(wchar_t out[1024], long n, mglArg *a, int k[10])const wchar_t *}
-Function for exporting in C++ (can be NULL).
-@end deftypecv
-
-
-@c ------------------------------------------------------------------
-@node mglArg class, mglVar class, mglPoint class, Other classes
-@section mglArg class
-@cindex mglArg
-
-Structure describes arguments of functions in the stucture @code{mglCommand}. It is defined in @code{#include <mgl/parse.h>}.
-
-@deftypecv {Parameter} mglArg @code{int} type
-Type of argument: 0-data, 1-string, 2-number.
-@end deftypecv
-@deftypecv {Parameter} mglArg @code{mglData *} d
-Pointer to data (used if type=0).
-@end deftypecv
-@deftypecv {Parameter} mglArg @code{wchar_t} w[2048]
-String with parameters (used if type=1 or if type=0 as variable name).
-@end deftypecv
-@deftypecv {Parameter} mglArg @code{char} s[2048]
-String with parameters (used if type=1).
-@end deftypecv
-@deftypecv {Parameter} mglArg @code{float} v
-Numerical value (used if type==2)
-@end deftypecv
-
index c9e53a004538cf45c07768b5cc423077fcb88f7c..0ceec7eff218c347eb7074a3469595789be98fda 100644 (file)
 @c ------------------------------------------------------------------
 @chapter MGL scripts
 
+MathGL library supports the simplest scripts for data handling and plotting. These scripts can be used independently (with the help of UDAV, mglconv, mglview programs and others
+@ifclear UDAV
+, @pxref{Utilities}) or in the frame of the library using.
+@end ifclear
+
+@ifclear UDAV
 @menu
+* MGL definition::
+* Program flow commands::
 * mglParse class::
 @end menu
+@end ifclear
+
+@ifset UDAV
+@menu
+* MGL definition::
+* Program flow commands::
+@end menu
+@end ifset
+
+
+@c ------------------------------------------------------------------
+@node MGL definition, Program flow commands, , MGL scripts
+@section MGL definition
+
+MGL script language is rather simple. Each string is a command. First word of string is the name of command. Other words are command arguments. Command may have up to 1000 arguments (at least for now). Words are separated from each other by space or tabulation symbol. The upper or lower case of words is important, i.e. variables @var{a} and @var{A} are different variables. Symbol @samp{#} starts the comment (all characters after # will be ignored). The exception is situation when @samp{#} is a part of some string. Also options can be specified after symbol @samp{;} (@pxref{Command options}). Symbol @samp{:} starts new command (like new line character) if it is not placed inside a string or inside brackets.
+
+If string contain references to external parameters (substrings @samp{$0}, @samp{$1} ... @samp{$9}) or definitions (substrings @samp{$a}, @samp{$b} ... @samp{$z}) then before execution the values of parameter/definition will be substituted instead of reference. It allows to use the same MGL script for different parameters (filenames, paths, condition and so on).
+
+Argument can be a string, a variable (data arrays) or a number (scalars).
+@itemize @bullet
+@item
+The string is any symbols between ordinary marks @samp{'}. Long strings can be concatenated from several lines by @samp{\} symbol. I.e. the string @samp{'a +'\<br>' b'} will give string @samp{'a + b'} (here @samp{<br>} is newline).
+
+@item
+Usually variable have a name which is arbitrary combination of symbols (except spaces and @samp{'}) started from a letter and with length less than 64. A temporary array can be used as variable:
+@itemize @bullet
+@item
+sub-arrays (like in @ref{subdata} command) as command argument. For example, @code{a(1)} or @code{a(1,:)} or @code{a(1,:,:)} is second row, @code{a(:,2)} or @code{a(:,2,:)} is third column, @code{a(:,:,0)} is first slice and so on. Also you can extract a part of array from m-th to n-th element by code @code{a(m:n,:,:)} or just @code{a(m:n)}.
+
+@item
+any column combinations defined by formulas, like @code{a('n*w^2/exp(t)')} if names for data columns was specified (by @ref{idset} command or in the file at string started with @code{##}).
+
+@item
+any expression (without spaces) of existed variables produce temporary variable. For example, @samp{sqrt(dat(:,5)+1)} will produce temporary variable with data values equal to @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}.
+
+@item
+temporary variable of higher dimensions by help of []. For example, @samp{[1,2,3]} will produce a temporary vector of 3 elements @{1, 2, 3@}; @samp{[[11,12],[21,22]]} will produce matrix 2*2 and so on. Here you can join even an arrays of the same dimensions by construction like @samp{[v1,v2,...,vn]}.
+
+@item
+result of code for making new data (@pxref{Make another data}) inside @{@}. For example, @samp{@{sum dat 'x'@}} produce temporary variable which contain result of summation of @var{dat} along direction 'x'. This is the same array @var{tmp} as produced by command @samp{sum tmp dat 'x'}. You can use nested constructions, like @samp{@{sum @{max dat 'z'@} 'x'@}}.
+@end itemize
+Temporary variables can not be used as 1st argument for commands which create (return) the data (like @samp{new}, @samp{read}, @samp{hist} and so on).
+
+@item
+Special names @code{nan=#QNAN, pi=3.1415926..., on=1, off=0, :=-1} are treated as number if they were not redefined by user. Variables with suffixes are treated as numbers (@pxref{Data information}). Names defined by @ref{define} command are treated as number. Also results of formulas with sizes 1x1x1 are treated as number (for example, @samp{pi/dat.nx}).
+@end itemize
+Before the first using all variables must be defined with the help of commands, like, @ref{new}, @ref{var}, @ref{list}, @ref{copy}, @ref{read}, @ref{hist}, @ref{sum} and so on (see sections @ref{Data constructor}, @ref{Data filling} and @ref{Make another data}).
+
+Command may have several set of possible arguments (for example, @code{plot ydat} and @code{plot xdat ydat}). All command arguments for a selected set must be specified. However, some arguments can have default values. These argument are printed in [], like @code{text ydat ['stl'='']} or @code{text x y 'txt' ['fnt'='' size=-1]}. At this, the record @code{[arg1 arg2 arg3 ...]} means @code{[arg1 [arg2 [arg3 ...]]]}, i.e. you can omit only tailing arguments if you agree with its default values. For example, @code{text x y 'txt' '' 1} or @code{text x y 'txt' ''} is correct, but @code{text x y 'txt' 1} is incorrect (argument @code{'fnt'} is missed).
+
 
 @c ------------------------------------------------------------------
-@node mglParse class, , , MGL scripts
+@node Program flow commands, MGL definition, MGL scripts
+@section Program flow commands
+
+Below I show commands to control program flow, like, conditions, loops, define script arguments and so on. Other commands can be found in chapters @ref{MathGL core} and @ref{Data processing}.
+
+@cindex chdir
+@anchor{chdir}
+@deftypefn {MGL command} {} chdir 'path'
+Changes the current directory to @var{path}.
+@end deftypefn
+
+@cindex ask
+@anchor{ask}
+@deftypefn {MGL command} {} ask $N 'question'
+Sets @var{N}-th script argument to answer which give the user on the @var{question}. Usually this show dialog with question where user can enter some text as answer. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+
+@cindex define
+@anchor{define}
+@deftypefn {MGL command} {} define $N smth
+Sets @var{N}-th script argument to @var{smth}. Note, that @var{smth} is used as is (with @samp{'} symbols if present). Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@deftypefn {MGL command} {} define name smth
+Create scalar variable @code{name} which have the numeric value of @code{smth}. Later you can use this variable as usual number. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@cindex defchr
+@anchor{defchr}
+@deftypefn {MGL command} {} defchr $N smth
+Sets @var{N}-th script argument to character with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@cindex defnum
+@anchor{defnum}
+@deftypefn {MGL command} {} defnum $N smth
+Sets @var{N}-th script argument to number with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@cindex defpal
+@anchor{defpal}
+@deftypefn {MGL command} {} defpal $N smth
+Sets @var{N}-th script argument to palette character at position evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+
+@cindex call
+@anchor{call}
+@deftypefn {MGL command} {} call 'fname' [ARG1 ARG2 ... ARG9]
+Executes function @var{fname} (or script if function is not found). Optional arguments will be passed to functions. See also @ref{func}.
+@end deftypefn
+@cindex func
+@anchor{func}
+@deftypefn {MGL command} {} func 'fname' [narg=0]
+Define the function @var{fname} and number of required arguments. The arguments will be placed in script parameters $1, $2, ... $9. Note, you should stop script execution before function definition(s) by command @ref{stop}. See also @ref{return}.
+@end deftypefn
+@cindex return
+@anchor{return}
+@deftypefn {MGL command} {} return
+Return from the function. See also @ref{func}.
+@end deftypefn
+
+
+@cindex if
+@anchor{if}
+@deftypefn {MGL command} {} if dat 'cond'
+Starts block which will be executed if @var{dat} satisfy to @var{cond}.
+@end deftypefn
+@deftypefn {MGL command} {} if @code{val}
+Starts block which will be executed if @code{val} is nonzero.
+@end deftypefn
+@cindex elseif
+@anchor{elseif}
+@deftypefn {MGL command} {} elseif dat 'cond'
+Starts block which will be executed if previous @code{if} or @code{elseif} is false and @var{dat} satisfy to @var{cond}.
+@end deftypefn
+@deftypefn {MGL command} {} elseif @code{val}
+Starts block which will be executed if previous @code{if} or @code{elseif} is false and @code{val} is nonzero.
+@end deftypefn
+@cindex else
+@anchor{else}
+@deftypefn {MGL command} {} else
+Starts block which will be executed if previous @code{if} or @code{elseif} is false.
+@end deftypefn
+@cindex endif
+@anchor{endif}
+@deftypefn {MGL command} {} endif
+Finishes @code{if/elseif/else} block.
+@end deftypefn
+
+@cindex for
+@anchor{for}
+@deftypefn {MGL command} {} for $N @code{v1 v2 [dv=1]}
+Starts cycle with $@var{N}-th argument changing from @var{v1} to @var{v2} with the step @var{dv}. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@deftypefn {MGL command} {} for $N dat
+Starts cycle with $@var{N}-th argument changing for @var{dat} values. Here @var{N} is digit (0...9) or alpha (a...z).
+@end deftypefn
+@cindex next
+@anchor{next}
+@deftypefn {MGL command} {} next
+Finishes @code{for} cycle.
+@end deftypefn
+
+@cindex once
+@anchor{once}
+@deftypefn {MGL command} {} once @code{val}
+The code between @code{once on} and @code{once off} will be executed only once. Useful for large data manipulation in programs like UDAV.
+@end deftypefn
+@cindex stop
+@anchor{stop}
+@deftypefn {MGL command} {} stop
+Terminate execution.
+@end deftypefn
+
+@ifclear UDAV
+@c ------------------------------------------------------------------
+@node mglParse class, , Program flow commands, MGL scripts
 @section mglParse class
 @cindex mglParse
 
 Class for parsing and executing MGL script. This class is defined in @code{#include <mgl/mgl.h>}.
 
-Class mglParse is the interpreter for MGL scripts (@pxref{MGL interface}). The main function of mglParse class is @code{Parse()}. Exactly this function parses and executes the script string-by-string. Also there are two subservient functions for the finding and creation of a variable. These functions can be useful for displaying values of variables (arrays) in some external program (in window, for example). The variable @var{DataList} contains full list of variables in script. Flag @var{AllowSetSize} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).
+Class mglParse is the interpreter for MGL scripts. The main function of mglParse class is @code{Execute()}. Exactly this function parses and executes the script string-by-string. Also there are subservient functions for the finding and creation of a variable. These functions can be useful for displaying values of variables (arrays) in some external program (in window, for example). Function @code{AllowSetSize()} allows one to prevent changing the size of the  picture inside the script (forbids the MGL command @code{setsize}).
 
 @c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
 
 @deftypefn {Constructor on @code{mglParse}} @code{} mglParse (@code{bool} setsize=@code{false})
+@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{HMPR} pr)
+@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{mglParse &}pr)
 @deftypefnx {C function} @code{HMPR} mgl_create_parser ()
 Constructor initializes all values with zero and set @var{AllowSetSize} value.
 @end deftypefn
@@ -27,30 +199,35 @@ Constructor initializes all values with zero and set @var{AllowSetSize} value.
 Destructor delete parser
 @end deftypefn
 
-@deftypefn {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
-@deftypefnx {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
-@deftypefnx {C function} @code{int} mgl_parse (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
-@deftypefnx {C function} @code{int} mgl_parsew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
-Main function in the class. It parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
+@deftypefn {Method on @code{mglParse}} @code{HMPR} Self ()
+Returns the pointer to internal object of type @code{HMPR}.
+@end deftypefn
+
+@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text)
+@deftypefnx{Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text)
+@deftypefnx {C function} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text)
+@deftypefnx {C function} @code{void} mgl_parsew_text (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text)
+Main function in the class. Function parse and execute line-by-line MGL script in array @var{text}. Lines are separated by newline symbol @samp{\n} as usual.
 @end deftypefn
 
 @deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{FILE *}fp, @code{bool} print=@code{false})
-@deftypefnx {C function} @code{int} mgl_parsew (@code{HMGL} gr, @code{HMPR} p, @code{FILE *}fp, @code{int} print)
-Function parse and execute line-by-line MGL script in file @var{fp}. If @var{print}=@code{true} then all warnings and information will be printed in stdout.
+@deftypefnx {C function} @code{int} mgl_parse_file (@code{HMGL} gr, @code{HMPR} p, @code{FILE *}fp, @code{int} print)
+The same as previous but read script from the file @var{fp}. If @var{print}=@code{true} then all warnings and information will be printed in stdout.
 @end deftypefn
 
-@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text, @code{void (*} error @code{)(int line, int kind, char *mes)=NULL})
-@deftypefnx{Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text, @code{void (*} error @code{)(int line, int kind, char *mes)=NULL})
-@deftypefnx {C function} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text, @code{void (*} error @code{)(int line, int kind, char *mes)})
-@deftypefnx {C function} @code{void} mgl_parsew_text (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text, @code{void (*} error @code{)(int line, int kind, char *mes)})
-Function parse and execute line-by-line MGL script in array @var{text}. Lines are separated by newline symbol @samp{\n} as usual. If @var{error} is not @code{NULL} then this function will be called for all warnings, information and other messages.
+@deftypefn {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
+@deftypefnx {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
+@deftypefnx {C function} @code{int} mgl_parse (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
+@deftypefnx {C function} @code{int} mgl_parsew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
+Function parses the string @var{str} and executes it by  using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
 @end deftypefn
 
-@deftypefn {Method on @code{mglParse}} @code{bool} AddParam (@code{int} n, @code{const char *}str, @code{bool} isstr=@code{true})
-@deftypefnx {Method on @code{mglParse} (C++)} @code{bool} AddParam (@code{int} n, @code{const wchar_t *}str, @code{bool} isstr=@code{true})
+
+@deftypefn {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const char *}str)
+@deftypefnx {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const wchar_t *}str)
 @deftypefnx {C function} @code{void} mgl_add_param (@code{HMPR} p, @code{int} id, @code{const char *}val)
 @deftypefnx {C function} @code{void} mgl_add_paramw (@code{HMPR} p, @code{int} id, @code{const wchar_t *}val)
-Function set the value of @var{n}-th parameter as string @var{str} (@var{n}=0, 1 ... 9). It return @code{true} for success.
+Function set the value of @var{n}-th parameter as string @var{str} (@var{n}=0, 1 ... 'z'-'a'+10). String @var{str} shouldn't contain @samp{$} symbol.
 @end deftypefn
 
 @deftypefn {Method on @code{mglParse}} @code{mglData *} FindVar (@code{const char *}name)
@@ -83,7 +260,19 @@ Sends stop signal which terminate execution at next command.
 @end deftypefn
 
 
-@deftypefn {Method on @code{mglParse}} @code{void} Stop ()
-@deftypefnx {C function} @code{void} mgl_parser_stop (@code{HMPR} p)
-Sends stop signal which terminate execution at next command.
+@deftypefn {Method on @code{mglParse}} @code{int} CmdType (@code{const char *}name)
+@deftypefnx {C function} @code{int} mgl_cmd_type (@code{HMPR} p, @code{const char *}name)
+Return the type of MGL command @var{name}. Type of commands are: 0 -- not the command, 1 - data plot, 2 - other plot, 3 - setup, 4 - data handle, 5 - create data, 6 - define subplot, 7 - program flow.
+@end deftypefn
+
+@deftypefn {Method on @code{mglParse}} @code{const char *} CmdFormat (@code{const char *}name)
+@deftypefnx {C function} @code{const char *} mgl_cmd_frmt (@code{HMPR} p, @code{const char *}name)
+Return the format of arguments for MGL command @var{name}.
+@end deftypefn
+
+@deftypefn {Method on @code{mglParse}} @code{const char *} CmdDesc (@code{const char *}name)
+@deftypefnx {C function} @code{const char *} mgl_cmd_desc (@code{HMPR} p, @code{const char *}name)
+Return the description of MGL command @var{name}.
 @end deftypefn
+
+@end ifclear
index 841d33cfbffab6c416812cb94fbf73ea32bec76f..584acfd33b8828a0565297417e9c20e3b0b5d95c 100644 (file)
@@ -5,13 +5,13 @@
   <title>MathGL 2.0</title>
 </head><body>
 
-<a target="main" href="web_en/web_en_1.html"><b>Home</b></a></p>
+<a target="main" href="web_en/web_en_1.html"><b>Main page</b></a></p>
 <a target="main" href="web_en/web_en_2.html"><b>News</b></a></p>
 <a target="main" href="web_en/web_en_3.html"><b>Features</b></a></p>
 <a target="main" href="web_en/web_en_4.html"><b>Pictures</b></a></p>
 <a target="main" href="web_en/web_en_5.html"><b>MGL scripts</b></a></p>
 <a target="main" href="web_en/web_en_6.html"><b>Download</b></a></p>
-<a target="main" href="web_en/web_en_7.html"><b>Documentation</b></a></p>
+<a target="main" href="mathgl_en/mathgl_en.html"><b>Documentation</b></a></p>
 <a target="main" href="web_en/web_en_8.html"><b>Other projects</b></a></p>
 
 <hr style="width: 100%; height: 1px;">
index 841d33cfbffab6c416812cb94fbf73ea32bec76f..7c9108c25bf790ba54ea3956a624e159022201c5 100644 (file)
@@ -5,14 +5,14 @@
   <title>MathGL 2.0</title>
 </head><body>
 
-<a target="main" href="web_en/web_en_1.html"><b>Home</b></a></p>
-<a target="main" href="web_en/web_en_2.html"><b>News</b></a></p>
-<a target="main" href="web_en/web_en_3.html"><b>Features</b></a></p>
-<a target="main" href="web_en/web_en_4.html"><b>Pictures</b></a></p>
-<a target="main" href="web_en/web_en_5.html"><b>MGL scripts</b></a></p>
-<a target="main" href="web_en/web_en_6.html"><b>Download</b></a></p>
-<a target="main" href="web_en/web_en_7.html"><b>Documentation</b></a></p>
-<a target="main" href="web_en/web_en_8.html"><b>Other projects</b></a></p>
+<a target="main" href="web_ru/web_ru_1.html"><b>Main page</b></a></p>
+<a target="main" href="web_ru/web_ru_2.html"><b>Новости</b></a></p>
+<a target="main" href="web_ru/web_ru_3.html"><b>Возможности</b></a></p>
+<a target="main" href="web_ru/web_ru_4.html"><b>Примеры</b></a></p>
+<a target="main" href="web_ru/web_ru_5.html"><b>Скрипты MGL</b></a></p>
+<a target="main" href="web_ru/web_ru_6.html"><b>Загрузка</b></a></p>
+<a target="main" href="mathgl_ru/mathgl_ru.html"><b>Документация</b></a></p>
+<a target="main" href="web_ru/web_ru_8.html"><b>Другие проекты</b></a></p>
 
 <hr style="width: 100%; height: 1px;">
 <g:plusone></g:plusone>
diff --git a/texinfo/web_fr.texi b/texinfo/web_fr.texi
new file mode 100644 (file)
index 0000000..65c0915
--- /dev/null
@@ -0,0 +1,523 @@
+\input texinfo
+@setfilename mgl_web_en.info
+@set VERSION 2.0
+@settitle MathGL @value{VERSION}
+@syncodeindex pg cp
+@comment %**end of header
+
+@copying
+This website demonstrates the Mathematical Graphic Library (MathGL) version @value{VERSION}, a collection of classes and routines for scientific plotting. Please report any errors in this manual to @email{mathgl.abalakin@@gmail.org}.
+
+Copyright @copyright{} 2008 Alexey Balakin.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.  A copy of the
+license is included in the section entitled ``GNU Free Documentation
+License.''
+
+(a) The FSF's Back-Cover Text is: ``You have the freedom to
+copy and modify this GNU manual.  Buying copies from the FSF
+supports it in developing GNU and promoting software freedom.''
+@end quotation
+@end copying
+
+@titlepage
+@title MathGL website
+@subtitle for version @value{VERSION}
+@author A.A. Balakin (@uref{http://mathgl.sourceforge.net/})
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@contents
+
+@ifnottex
+@node Top
+@top MathGL
+
+This website demonstrates the Mathematical Graphic Library (MathGL), a collection of classes and routines for scientific plotting. It corresponds to release @value{VERSION} of the library. Please report any errors in this manual to @email{mathgl.abalakin@@gmail.org}. More information about MathGL can be found at the project homepage, @uref{http://mathgl.sourceforge.net/}.
+
+Copyright @copyright{} 2008 Alexey A. Balakin.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
+and with the Back-Cover Texts as in (a) below.  A copy of the
+license is included in the section entitled ``GNU Free Documentation
+License.''
+
+(a) The FSF's Back-Cover Text is: ``You have the freedom to
+copy and modify this GNU manual.  Buying copies from the FSF
+supports it in developing GNU and promoting software freedom.''
+@end quotation
+
+@end ifnottex
+
+@menu
+* Main::
+* News::
+* Features::
+* Pictures::
+* MGL scripts::
+* Download::
+* Other projects::
+@end menu
+
+@ifhtml
+@macro external {}
+@html
+<!--LiveInternet counter--><script type="text/javascript"><!--
+document.write("<a href='http://www.liveinternet.ru/click' "+
+"target=_blank><img src='http://counter.yadro.ru/hit?t12.2;r"+
+escape(document.referrer)+((typeof(screen)=="undefined")?"":
+";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?
+screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
+";"+Math.random()+
+"' alt='' title='LiveInternet: number of views during 24"+
+" hours, number of visitors during 24 hours and during today' "+
+"border=0 width=88 height=31><\/a>")//--></script><!--/LiveInternet-->
+
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=152187&amp;type=2" alt="SourceForge.net Logo" border="0" height="37" width="125"></a>
+
+<a href="http://www.thefreecountry.com/"> <img src="http://www.thefreecountry.com/images/tfc88x31green.gif" alt="thefreecountry.com: Free Programmers' Resources, Free Webmasters' Resources, Free Security Resources, Free Software" border="0" height="31" width="88"></a>
+
+<a href="http://sourceforge.net/donate/index.php?group_id=152187"><img src="http://images.sourceforge.net/images/project-support.jpg" width="88" height="32" border="0" alt="Support This Project" /> </a>
+@end html
+@end macro
+@macro fig {plot,text}
+@uref{../\text\, @image{../small/\plot\_sm,3cm, , , .png}}
+@end macro
+@end ifhtml
+
+@ifnothtml
+@macro external {}
+@end macro
+@macro fig {plot,text}
+@uref{http://mathgl.sourceforge.net/\text\, @image{small/\plot\_sm,3cm, , , .png}}
+@end macro
+@end ifnothtml
+
+@node Main, News, , Top
+@section MathGL is ...
+
+@ifhtml
+@html
+<a href="surf_cont_fog.html"><img border="0" align="right" hspace="30" vspace="20" alt="Surface in fog" src="../surf_cont_fog_g.png"></a>
+@end html
+@end ifhtml
+@itemize @bullet
+@item
+a library for making high-quality scientific graphics under Linux and Windows;
+@item
+a library for the fast data plotting and data processing of large data arrays;
+@item
+a library for working in window and console modes and for easy embedding into other programs;
+@item
+a library with large and growing set of graphics.
+@end itemize
+
+At this version (1.11) MathGL has more than 35000 lines of code, more than 55 general types of graphics for 1d, 2d and 3d data arrays, including special ones for chemical and statistical graphics. It can export graphics to raster and vector (EPS or SVG) formats. It has Qt, FLTK, OpenGL interfaces and can be used even from console programs. It has functions for data processing and script MGL language for simplification of data plotting. Also it has several types of transparency and smoothed lightning, vector fonts and TeX-like symbol parsing, arbitrary curvilinear coordinate system and many over useful things. It can be used from code written on C++/C/Fortran/Python/Octave and many other languages. Finally it is platform independent and free (under GPL v.2.0 license).
+
+There is a @uref{http://sourceforge.net/forum/?group_id=152187, forum} where you can ask a question or suggest an improvement. However the @uref{http://groups.google.com/group/mathgl, MathGL group} is preferable for quicker answer.
+
+For subscribing to @uref{http://groups.google.com/group/mathgl, MathGL group} you can use form below
+@ifhtml
+@html
+<form action="http://groups.google.com/group/mathgl/boxsubscribe">
+Email: <input type=text name=email> <input type=submit name="sub" value="Subscribe">
+</form>
+@end html
+@end ifhtml
+
+@strong{About LGPL and GPL licenses.}
+Generally MathGL is GPL library. However, you can use LGPL license for MathGL core if you don't use wrapper widget classes, SWIG-based interfaces and disable GSL features. This can be done by using @code{lgpl} option at build time. According this, I've added the LGPL win32 binaries into @ref{Download} page.
+
+@strong{Latest news}
+@itemize
+@item @emph{29 March 2012.}
+New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted @ref{News, here}.
+@end itemize
+
+There is detailed @ref{News, news list}. Sourceforge project page @uref{http://sourceforge.net/projects/mathgl/, here}.
+
+@external
+
+@node News, Features, Main, Top
+@section News
+
+@itemize
+@item 
+@strong{29 March 2012.}
+New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted below.
+@itemize @bullet
+@item
+mglGraph class is single plotter class instead of mglGraphZB, mglGraphPS and so on.
+@item
+Text style and text color positions are swapped. I.e. text style @samp{r:C} give red centered text, but not roman dark cyan text as for v.1.*.
+@item
+ColumnPlot() indexing is reverted.
+@item
+Move most of arguments of plotting functions into the string parameter and/or options.
+@item
+``Bright'' colors (like @{b8@}) can be used in color schemes and line styles.
+@item
+Intensively use pthread internally for parallelization of drawing and data processing.
+@item
+Add tick labels rotation and skipping. Add ticks in time/date format.
+@item
+New kinds of plots (Tape(), Label(), Cones(), ContV()). Extend existing plots. New primitives (Circle(), Ellipse(), Rhomb(), ...). New plot positioning (MultiPlot(), GridPlot())
+@item
+Improve MGL scripts. Add 'ask' command and allow string concatenation from different lines.
+@item
+Export to LaTeX and to 3D formats (OBJ, OFF, STL).
+@item
+Add pipes support in utilities (@code{mglconv, mglview}).
+@end itemize
+
+@item 
+@strong{23 August 2011.} Version 2.0.beta was released.
+@item 
+@strong{30 May 2011.} Version 1.11.2 was released.
+@item 
+@strong{8 November 2010.} Version 1.11 was released.
+@item 
+@strong{28 December 2009.} Version 1.10 was released.
+@item 
+@strong{8 July 2009.} Version 1.9 was released.
+@item 
+@strong{27 November 2008.} Version 1.8 was released.
+@item 
+@strong{5 June 2008.} Version 1.7 was released.
+@item 
+@strong{17 March 2008.} Version 1.6 was released.
+@item 
+@strong{11 January 2008.} Version 1.5 was released.
+@item 
+@strong{30 October 2007.} Version 1.4 was released.
+@item 
+@strong{15 October 2007.} Version 1.3 was released.
+@item 
+@strong{10 September 2007.} Version 1.2 was released.
+@item 
+@strong{23 May 2007.} Version 1.1 was released.
+@item 
+@strong{2 April 2007.} Version 1.0 was released.
+@item 
+@strong{24 January 2007.} First public release (v.0.8).
+@end itemize
+
+@external
+
+
+@node Features, Pictures, News, Top
+@section Features
+
+MathGL can plot a wide range of graphics. It includes:
+@itemize @bullet
+@item
+one-dimensional: Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, (@ref{1D plotting});
+
+@item
+two-dimensional plots: Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, including surfaces transparent (SurfA) or colored (SurfC) by another data (@ref{2D plotting});
+
+@item
+three-dimensional plots: Surf3, Dens3, Cont3, ContF3, Cloud-like, including isosurfaces transparent (Surf3A) or colored (Surf3C) by another data (@ref{3D plotting});
+
+@item
+vector fields plots: vector fields Vect and Traj, flow threads Flow, flow pipes Pipe, mapping chart Map, and so on (@ref{Vector fields});
+
+@item
+and so on. See also @ref{Extra samples}.
+@end itemize
+
+In fact, I created the functions for drawing of all the types of scientific plots that I know. The list of plots is growing; if you need some special type of a plot then please email me @email{mathgl.abalakin@@gmail.com, e-mail} and it will appear in the new version.
+
+I tried to make plots as nice looking as possible: e.g., a surface can be transparent and highlighted by several (up to 10) light sources. Most of the drawing functions have 2 variants: simple one for the fast plotting of data, complex one for specifying of the exact position of the plot (including parametric representation). Resulting image can be saved in bitmap PNG, JPEG, TGA, BMP format, or in vector EPS, SVG or TeX format, or in 3D formats OBJ, OFF, STL or in IDTF format which can be converted into U3D.
+
+All texts are drawn by vector fonts, which allows for high scalability and portability. Texts may contain commands for: some of the TeX-like symbols, changing index (upper or lower indexes) and the style of font inside the text string. Texts of ticks are rotated with axis rotation. It is possible to create a legend of plot and put text in an arbitrary position on the plot. Arbitrary text encoding (by the help of function @code{setlocale()}) and UTF-16 encoding are supported.
+
+Special class mglData is used for data encapsulation. In addition to a safe creation and deletion of data arrays it includes functions for data processing (smoothing, differentiating, integrating, interpolating and so on) and reading of data files with automatic size determination. Class mglData can handle arrays with up to three dimensions (arrays which depend on up to 3 independent indexes @math{a_@{ijk@}}). Using an array with higher number of dimensions is not meaningful, because I do not know how it can be plotted. Data filling and modification may be done manually or by textual formulas.
+
+There is fast evaluation of a textual mathematical expression. It is based on string precompilation to tree-like code at the creation of class instance. At evaluation stage code performs only fast tree-walk and returns the value of the expression. In addition to changing data values, textual formulas are also used for drawing in @emph{arbitrary} curvilinear coordinates. A set of such curvilinear coordinates is limited only by user's imagination rather than a fixed list like: polar, parabolic, spherical, and so on.
+
+@external
+
+@node Pictures, MGL scripts, Features, Top
+@section Pictures
+
+There are samples for @ref{1D plotting, 1D arrays}, @ref{2D plotting, 2D arrays}, @ref{3D plotting, 3D arrays}, @ref{Vector fields} and some @ref{Extra samples}.
+
+@anchor{1D plotting}
+@subsection Examples of graphics for 1d arrays
+
+@fig{plot, mathgl_en/mathgl_en_13.html#Plot-sample}
+@fig{radar, mathgl_en/mathgl_en_13.html#Radar-sample}
+@fig{step, mathgl_en/mathgl_en_13.html#Step-sample}
+@fig{tens, mathgl_en/mathgl_en_13.html#Tens-sample}
+
+@fig{area, mathgl_en/mathgl_en_13.html#Area-sample}
+@fig{region, mathgl_en/mathgl_en_13.html#Region-sample}
+@fig{stem, mathgl_en/mathgl_en_13.html#Stem-sample}
+@fig{torus, mathgl_en/mathgl_en_13.html#Torus-sample}
+
+@fig{bars, mathgl_en/mathgl_en_13.html#Bars-sample}
+@fig{barh, mathgl_en/mathgl_en_13.html#Barh-sample}
+@fig{cones, mathgl_en/mathgl_en_13.html#Cones-sample}
+@fig{chart, mathgl_en/mathgl_en_13.html#Chart-sample}
+
+@fig{boxplot, mathgl_en/mathgl_en_13.html#BoxPlot-sample}
+@fig{candle, mathgl_en/mathgl_en_13.html#Candle-sample}
+@fig{tube, mathgl_en/mathgl_en_13.html#Tube-sample}
+@fig{tape, mathgl_en/mathgl_en_13.html#Tape-sample}
+
+@fig{error, mathgl_en/mathgl_en_13.html#Error-sample}
+@fig{mark, mathgl_en/mathgl_en_13.html#Mark-sample}
+@fig{textmark, mathgl_en/mathgl_en_13.html#TextMark-sample}
+@fig{label, mathgl_en/mathgl_en_13.html#Label-sample}
+
+@anchor{2D plotting}
+@subsection Examples of graphics for 2d arrays
+
+@fig{surf, mathgl_en/mathgl_en_14.html#Surf-sample}
+@fig{surfc, mathgl_en/mathgl_en_14.html#SurfC-sample}
+@fig{surfa, mathgl_en/mathgl_en_14.html#SurfA-sample}
+@fig{mesh, mathgl_en/mathgl_en_14.html#Mesh-sample}
+
+@fig{fall, mathgl_en/mathgl_en_14.html#Fall-sample}
+@fig{belt, mathgl_en/mathgl_en_14.html#Belt-sample}
+@fig{boxs, mathgl_en/mathgl_en_14.html#Boxs-sample}
+@fig{axial, mathgl_en/mathgl_en_14.html#Axial-sample}
+
+@fig{dens, mathgl_en/mathgl_en_14.html#Dens-sample}
+@fig{tile, mathgl_en/mathgl_en_14.html#Tile-sample}
+@fig{tiles, mathgl_en/mathgl_en_14.html#TileS-sample}
+@fig{grad, mathgl_en/mathgl_en_14.html#Grad-sample}
+
+@fig{cont, mathgl_en/mathgl_en_14.html#Cont-sample}
+@fig{contf, mathgl_en/mathgl_en_14.html#ContF-sample}
+@fig{contd, mathgl_en/mathgl_en_14.html#ContD-sample}
+@fig{contv, mathgl_en/mathgl_en_14.html#ContV-sample}
+
+@anchor{3D plotting}
+@subsection Examples of graphics for 3d arrays
+
+@fig{surf3, mathgl_en/mathgl_en_15.html#Surf3-sample}
+@fig{surf3c, mathgl_en/mathgl_en_15.html#Surf3C-sample}
+@fig{surf3a, mathgl_en/mathgl_en_15.html#Surf3A-sample}
+@fig{cloud, mathgl_en/mathgl_en_15.html#Cloud-sample}
+
+@fig{densa, mathgl_en/mathgl_en_15.html#Dens3-sample}
+@fig{conta, mathgl_en/mathgl_en_15.html#Cont3-sample}
+@fig{contfa, mathgl_en/mathgl_en_15.html#ContF3-sample}
+@fig{dots, mathgl_en/mathgl_en_15.html#Dots-sample}
+
+@fig{dens_xyz, mathgl_en/mathgl_en_15.html#Dens-projection-sample}
+@fig{cont_xyz, mathgl_en/mathgl_en_15.html#Cont-projection-sample}
+@fig{contf_xyz, mathgl_en/mathgl_en_15.html#ContF-projection-sample}
+@fig{triplot, mathgl_en/mathgl_en_15.html#TriPlot-and-QuadPlot}
+
+@anchor{Vector fields}
+@subsection Examples of graphics for vector fields
+
+@fig{vect, mathgl_en/mathgl_en_16.html#Vect-sample}
+@fig{traj, mathgl_en/mathgl_en_16.html#Tra-sjample}
+@fig{flow, mathgl_en/mathgl_en_16.html#Flow-sample}
+@fig{pipe, mathgl_en/mathgl_en_16.html#Pipe-sample}
+
+@anchor{Extra samples}
+@subsection Examples of additional features
+
+@fig{inplot, mathgl_en/mathgl_en_10.html#Subplots}
+@fig{axis, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+@fig{ticks, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+@fig{loglog, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+
+@fig{curvcoor, mathgl_en/mathgl_en_10.html#Curvilinear-coordinates}
+@fig{colorbar, mathgl_en/mathgl_en_10.html#Colorbars}
+@fig{box, mathgl_en/mathgl_en_10.html#Bounding-box}
+@fig{ternary, mathgl_en/mathgl_en_10.html#Ternary-axis}
+
+@fig{text, mathgl_en/mathgl_en_10.html#Text-features}
+@fig{legend, mathgl_en/mathgl_en_10.html#Legend-sample}
+@fig{cut, mathgl_en/mathgl_en_10.html#Cutting-sample}
+@fig{alpha, mathgl_en/mathgl_en_17.html#Transparency-and-lighting}
+
+@fig{type0, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{type1, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{type2, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{fog, mathgl_en/mathgl_en_17.html#Adding-fog}
+
+@fig{combined, mathgl_en/mathgl_en_17.html#g_t_0060_0060Compound_0027_0027-graphics}
+@fig{several_light, mathgl_en/mathgl_en_17.html#Several-light-sources}
+@fig{stereo, mathgl_en/mathgl_en_17.html#Stereo-image}
+@fig{primitives, mathgl_en/mathgl_en_17.html#Using-primitives}
+
+@fig{stfa, mathgl_en/mathgl_en_17.html#STFA-sample}
+@fig{dat_diff, mathgl_en/mathgl_en_11.html#Change-data}
+@fig{dat_extra, mathgl_en/mathgl_en_11.html#Change-data}
+@fig{map, mathgl_en/mathgl_en_17.html#Mapping-visualization}
+
+@fig{hist, mathgl_en/mathgl_en_17.html#Making-histogram}
+@fig{fit, mathgl_en/mathgl_en_17.html#Nonlinear-fitting-sample}
+@fig{pde, mathgl_en/mathgl_en_17.html#PDE-solving-hints}
+@fig{parser, mathgl_en/mathgl_en_17.html#MGL-parser-using}
+
+@external
+
+@node MGL scripts, Download, Pictures, Top
+@section MGL scripts
+
+MGL script language is rather simple. Each string is a command. First word of string is the name of command. Other words are command arguments. Command may have up to 1000 arguments (at least for now). Words are separated from each other by space or tabulation symbol. The upper or lower case of words is important, i.e. variables @var{a} and @var{A} are different variables. Symbol @samp{#} starts the comment (all characters after # will be ignored). The exception is situation when @samp{#} is a part of some string. Also options can be specified after symbol @samp{;}. Symbol @samp{:} starts new command (like new line character) if it is not placed inside a string or inside brackets.
+
+If string contain references to external parameters (substrings @samp{$0}, @samp{$1} ... @samp{$9}) or definitions (substrings @samp{$a}, @samp{$b} ... @samp{$z}) then before execution the values of parameter/definition will be substituted instead of reference. It allows to use the same MGL script for different parameters (file names, paths, condition and so on).
+
+Argument can be a string, a variable (data arrays) or a number (scalars).
+@itemize @bullet
+@item
+The string is any symbols between ordinary marks @samp{'}. Long strings can be concatenated from several lines by @samp{\} symbol. I.e. the string @samp{'a +'\<br>' b'} will give string @samp{'a + b'} (here @samp{<br>} is newline).
+
+@item
+Usually variable have a name which is arbitrary combination of symbols (except spaces and @samp{'}) started from a letter and with length less than 64. A temporary array can be used as variable:
+@itemize @bullet
+@item
+sub-arrays (like in @code{subdata} command) as command argument. For example, @code{a(1)} or @code{a(1,:)} or @code{a(1,:,:)} is second row, @code{a(:,2)} or @code{a(:,2,:)} is third column, @code{a(:,:,0)} is first slice and so on. Also you can extract a part of array from m-th to n-th element by code @code{a(m:n,:,:)} or just @code{a(m:n)}.
+
+@item
+any column combinations defined by formulas, like @code{a('n*w^2/exp(t)')} if names for data columns was specified (by @code{idset} command or in the file at string started with @code{##}).
+
+@item
+any expression (without spaces) of existed variables produce temporary variable. For example, @samp{sqrt(dat(:,5)+1)} will produce temporary variable with data values equal to @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}.
+
+@item
+temporary variable of higher dimensions by help of []. For example, @samp{[1,2,3]} will produce a temporary vector of 3 elements @{1, 2, 3@}; @samp{[[11,12],[21,22]]} will produce matrix 2*2 and so on. Here you can join even an arrays of the same dimensions by construction like @samp{[v1,v2,...,vn]}.
+
+@item
+result of code for making new data inside @{@}. For example, @samp{@{sum dat 'x'@}} produce temporary variable which contain result of summation of @var{dat} along direction 'x'. This is the same array @var{tmp} as produced by command @samp{sum tmp dat 'x'}. You can use nested constructions, like @samp{@{sum @{max dat 'z'@} 'x'@}}.
+@end itemize
+Temporary variables can not be used as 1st argument for commands which create (return) the data (like @samp{new}, @samp{read}, @samp{hist} and so on).
+
+@item
+Special names @code{nan=#QNAN, pi=3.1415926..., on=1, off=0, :=-1} are treated as number if they were not redefined by user. Variables with suffixes are treated as numbers. Names defined by @code{define} command are treated as number. Also results of formulas with sizes 1x1x1 are treated as number (for example, @samp{pi/dat.nx}).
+@end itemize
+Before the first using all variables must be defined with the help of commands, like, @code{new}, @code{var}, @code{list}, @code{copy}, @code{read}, @code{hist}, @code{sum} and so on.
+
+Command may have several set of possible arguments (for example, @code{plot ydat} and @code{plot xdat ydat}). All command arguments for a selected set must be specified. However, some arguments can have default values. These argument are printed in [], like @code{text ydat ['stl'='']} or @code{text x y 'txt' ['fnt'='' size=-1]}. At this, the record @code{[arg1 arg2 arg3 ...]} means @code{[arg1 [arg2 [arg3 ...]]]}, i.e. you can omit only tailing arguments if you agree with its default values. For example, @code{text x y 'txt' '' 1} or @code{text x y 'txt' ''} is correct, but @code{text x y 'txt' 1} is incorrect (argument @code{'fnt'} is missed).
+
+For more details see @uref{../mathgl_en/mathgl_en_64.html#MGL-scripts, MathGL documentation}
+
+@external
+
+@node Download, Other projects, MGL scripts, Top
+@section Download
+
+@strong{Stable version (v.2.0)}
+
+You may download current version of MathGL for following configurations:
+@itemize @bullet
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-2.0.tar.gz,source} file with autoconf/automake script.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-2.0-mingw.i686.zip,Win32 GPL} binaries for MinGW (build for i686)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-2.0.LGPL-mingw.i686.zip,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-2.0-1.DevPack,DevPak} package for Dev-C++ or Code::Blocks (GPL version)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-2.0.eng.pdf,PDF} documentation in English
+@c HTML documentation in English
+@c HTML documentation in Russian
+@c @item
+@c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
+@end itemize
+
+@strong{Previous version (v.1.11.2)}
+
+You may download current version of MathGL for following configurations:
+@itemize @bullet
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2.tar.gz,source} file with autoconf/automake script.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2-mingw.i686.zip,Win32 GPL} binaries for MinGW (build for i686)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.1.1.LGPL-mingw.i686.zip,Win32 LGPL} binaries for MinGW (build for i686, no GSL and HDF5 support)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2-1.DevPack,DevPak} package for Dev-C++ or Code::Blocks (GPL version)
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl-1.11.2.eng.pdf,PDF} documentation in English
+@c HTML documentation in English
+@c HTML documentation in Russian
+@item
+@uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
+@end itemize
+
+@strong{Font files}
+
+There are a set of @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=267177,font files} for MathGL with following typefaces. Note, that the set of glyphs can be less than in default font. As result not all TeX symbols can be displayed.
+@itemize @bullet
+@item
+@uref{http://downloads.sourceforge.net/mathgl/STIX_font.tgz,STIX} font -- default font for MathGL.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/adventor_font.tgz,Adventor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Gothic L family (like Avant Garde Gothic).
+@item
+@uref{http://downloads.sourceforge.net/mathgl/bonum_font.tgz,Bonum font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Bookman L family.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/chorus_font.tgz,Chorus font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} font based on the URW Chancery L Medium Italic.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/cursor_font.tgz,Cursor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} monospaced serif font based on the URW Nimbus Mono L (like Courier).
+@item
+@uref{http://downloads.sourceforge.net/mathgl/heros_font.tgz,Heros font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Nimbus Sans L (like Helvetica).
+@item
+@uref{http://downloads.sourceforge.net/mathgl/heroscn_font.tgz,HerosCN font} -- the "compressed" version of previous one.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/pagella_font.tgz,Pagella font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Palladio L (like Palatino).
+@item
+@uref{http://downloads.sourceforge.net/mathgl/schola_font.tgz,Schola font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the URW Century Schoolbook L.
+@item
+@uref{http://downloads.sourceforge.net/mathgl/termes_font.tgz,Termes font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the Nimbus Roman No9 L (like Times).
+@end itemize
+
+@external
+
+@node Other projects, , Download, Top
+@section Other projects
+
+Except scientific (non public) projects I also have some general interest projects:
+@itemize @bullet
+@item
+@uref{http://sourceforge.net/projects/pocketmk/, PocketMK} is small program for PocketPC which simulate famous Russian calculators MK-61 and slightly extend it.
+@item
+@uref{http://udav.sourceforge.net/,UDAV} is front-end for MGL scripts. It has windows interface for data viewing, changing and plotting. Also it can execute MGL scripts, setup and rotating graphics and so on.
+@end itemize
+
+Also I recommend to look at:
+@itemize @bullet
+@item
+@uref{http://englab.bugfest.net/,EngLab} is a cross-compile mathematical platform with a C like syntax intended to be used both by engineers and users with small programming knowledge. It is extremely scalable and allows users and the community to easily compile their own functions as shared objects.
+@item
+@uref{http://threedepict.sourceforge.net/,3Depict} is software for analysis of scientific datasets commonly encountered in atom probe tomography. You can manipulate, interact with and analyse point based datasets.
+@item
+@uref{http://www.sourceforge.net/projects/graphplot/,Graphplot} is function plotter based on MathGL.
+@item
+@uref{http://www.sourceforge.net/projects/graphplot/,OscillViewer} is oscilloscope monitoring program. Working with L-Card 14-140 AD-Convertor. Based on Qt and MathGL libraries.
+@end itemize
+
+Finally, few links to free software and libraries:
+@itemize @bullet
+@item
+@uref{http://www.thefreecountry.com/,thefreecountry.com} have a lot of Free Programmers', Webmasters' and Security Resources
+@item
+@uref{http://gnuwin32.sourceforge.net/,GnuWin} provides ports of tools with a GNU or similar open source license, to modern MS-Windows.
+@item
+@uref{http://loll.sourceforge.net/,LLoL} is project collecting, organising, classifying, and maintaining important URLs about Linux and the Open Source movement for all levels of Linux users. The LoLL project now has 4000+ links which are updated usually on a daily basis.
+@end itemize
+
+@external
+
+@bye
index 184e1727f539dccc0a18cc1116b9603179828a50..65c09155d2a9c5759b02904579f8b4fb0ee24eab 100644 (file)
@@ -61,21 +61,17 @@ supports it in developing GNU and promoting software freedom.''
 @end ifnottex
 
 @menu
-* MathGL is ...::
+* Main::
 * News::
 * Features::
 * Pictures::
 * MGL scripts::
 * Download::
-* Documentation::
 * Other projects::
 @end menu
 
-@macro fig {fname,text}
-@center @image{../\fname\, 11cm, , \text\, .png}
-@end macro
-
-@macro external
+@ifhtml
+@macro external {}
 @html
 <!--LiveInternet counter--><script type="text/javascript"><!--
 document.write("<a href='http://www.liveinternet.ru/click' "+
@@ -88,21 +84,34 @@ screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
 " hours, number of visitors during 24 hours and during today' "+
 "border=0 width=88 height=31><\/a>")//--></script><!--/LiveInternet-->
 
-<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=152187&amp;type=2" alt="SourceForge.net Logo" border="0" height="37" width="125"></a> 
+<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=152187&amp;type=2" alt="SourceForge.net Logo" border="0" height="37" width="125"></a>
 
-<a href="http://www.thefreecountry.com/"> <img src="http://www.thefreecountry.com/images/tfc88x31green.gif" alt="thefreecountry.com: Free Programmers' Resources, Free Webmasters' Resources, Free Security Resources, Free Software" border="0" height="31" width="88"></a> 
+<a href="http://www.thefreecountry.com/"> <img src="http://www.thefreecountry.com/images/tfc88x31green.gif" alt="thefreecountry.com: Free Programmers' Resources, Free Webmasters' Resources, Free Security Resources, Free Software" border="0" height="31" width="88"></a>
 
 <a href="http://sourceforge.net/donate/index.php?group_id=152187"><img src="http://images.sourceforge.net/images/project-support.jpg" width="88" height="32" border="0" alt="Support This Project" /> </a>
 @end html
 @end macro
+@macro fig {plot,text}
+@uref{../\text\, @image{../small/\plot\_sm,3cm, , , .png}}
+@end macro
+@end ifhtml
 
+@ifnothtml
+@macro external {}
+@end macro
+@macro fig {plot,text}
+@uref{http://mathgl.sourceforge.net/\text\, @image{small/\plot\_sm,3cm, , , .png}}
+@end macro
+@end ifnothtml
 
-@node MathGL is ..., News, , Top
+@node Main, News, , Top
 @section MathGL is ...
 
+@ifhtml
 @html
-<a href="surf_cont_fog.html"><img border="0" align="right" hspace="30" vspace="20" alt="Surface in fog" src="surf_cont_fog_g.png"></a>
+<a href="surf_cont_fog.html"><img border="0" align="right" hspace="30" vspace="20" alt="Surface in fog" src="../surf_cont_fog_g.png"></a>
 @end html
+@end ifhtml
 @itemize @bullet
 @item
 a library for making high-quality scientific graphics under Linux and Windows;
@@ -119,11 +128,13 @@ At this version (1.11) MathGL has more than 35000 lines of code, more than 55 ge
 There is a @uref{http://sourceforge.net/forum/?group_id=152187, forum} where you can ask a question or suggest an improvement. However the @uref{http://groups.google.com/group/mathgl, MathGL group} is preferable for quicker answer.
 
 For subscribing to @uref{http://groups.google.com/group/mathgl, MathGL group} you can use form below
+@ifhtml
 @html
 <form action="http://groups.google.com/group/mathgl/boxsubscribe">
 Email: <input type=text name=email> <input type=submit name="sub" value="Subscribe">
 </form>
 @end html
+@end ifhtml
 
 @strong{About LGPL and GPL licenses.}
 Generally MathGL is GPL library. However, you can use LGPL license for MathGL core if you don't use wrapper widget classes, SWIG-based interfaces and disable GSL features. This can be done by using @code{lgpl} option at build time. According this, I've added the LGPL win32 binaries into @ref{Download} page.
@@ -131,20 +142,20 @@ Generally MathGL is GPL library. However, you can use LGPL license for MathGL co
 @strong{Latest news}
 @itemize
 @item @emph{29 March 2012.}
-New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted @uref{TODO, here}.
+New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted @ref{News, here}.
 @end itemize
 
 There is detailed @ref{News, news list}. Sourceforge project page @uref{http://sourceforge.net/projects/mathgl/, here}.
 
 @external
 
-@node News, Features, MathGL is ..., Top
+@node News, Features, Main, Top
 @section News
 
 @itemize
 @item 
 @strong{29 March 2012.}
-New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted @uref{TODO, here}.
+New version (v.2.0) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are a lot of new features, which partially denoted below.
 @itemize @bullet
 @item
 mglGraph class is single plotter class instead of mglGraphZB, mglGraphPS and so on.
@@ -165,7 +176,7 @@ New kinds of plots (Tape(), Label(), Cones(), ContV()). Extend existing plots. N
 @item
 Improve MGL scripts. Add 'ask' command and allow string concatenation from different lines.
 @item
-Export to LaTeX and to 3D formats (OBJ, OFF, STL, X3D).
+Export to LaTeX and to 3D formats (OBJ, OFF, STL).
 @item
 Add pipes support in utilities (@code{mglconv, mglview}).
 @end itemize
@@ -211,19 +222,16 @@ Add pipes support in utilities (@code{mglconv, mglview}).
 MathGL can plot a wide range of graphics. It includes:
 @itemize @bullet
 @item
-one-dimensional (Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, @ref{1D plotting});
-
-@item
-two-dimensional plots (Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, @ref{2D plotting});
+one-dimensional: Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, (@ref{1D plotting});
 
 @item
-three-dimensional plots (Surf3, Dens3, Cont3, ContF3, Cloud-like, @ref{3D plotting});
+two-dimensional plots: Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, including surfaces transparent (SurfA) or colored (SurfC) by another data (@ref{2D plotting});
 
 @item
-vector fields plots: vector fields Vect and Traj, flow threads Flow, flow pipes Pipe, mapping chart Mapand so on (@ref{Vector fields});
+three-dimensional plots: Surf3, Dens3, Cont3, ContF3, Cloud-like, including isosurfaces transparent (Surf3A) or colored (Surf3C) by another data (@ref{3D plotting});
 
 @item
-dual data plots: surfaces and isosurfaces, transparent or colored (i.e. with transparency or color varied) by other data SurfA, SurfC, Surf3A, Surf3C (@ref{Dual plotting});
+vector fields plots: vector fields Vect and Traj, flow threads Flow, flow pipes Pipe, mapping chart Map, and so on (@ref{Vector fields});
 
 @item
 and so on. See also @ref{Extra samples}.
@@ -231,7 +239,7 @@ and so on. See also @ref{Extra samples}.
 
 In fact, I created the functions for drawing of all the types of scientific plots that I know. The list of plots is growing; if you need some special type of a plot then please email me @email{mathgl.abalakin@@gmail.com, e-mail} and it will appear in the new version.
 
-I tried to make plots as nice looking as possible: e.g., a surface can be transparent and highlighted by several (up to 10) light sources. Most of the drawing functions have 2 variants: simple one for the fast plotting of data, complex one for specifying of the exact position of the plot (including parametric representation). Resulting image can be saved in bitmap PNG, JPEG, TGA, BMP format, or in vector EPS, SVG or TeX format, or in 3D formats OBJ, OFF, STL or X3D, or in IDTF format which can be converted into U3D.
+I tried to make plots as nice looking as possible: e.g., a surface can be transparent and highlighted by several (up to 10) light sources. Most of the drawing functions have 2 variants: simple one for the fast plotting of data, complex one for specifying of the exact position of the plot (including parametric representation). Resulting image can be saved in bitmap PNG, JPEG, TGA, BMP format, or in vector EPS, SVG or TeX format, or in 3D formats OBJ, OFF, STL or in IDTF format which can be converted into U3D.
 
 All texts are drawn by vector fonts, which allows for high scalability and portability. Texts may contain commands for: some of the TeX-like symbols, changing index (upper or lower indexes) and the style of font inside the text string. Texts of ticks are rotated with axis rotation. It is possible to create a legend of plot and put text in an arbitrary position on the plot. Arbitrary text encoding (by the help of function @code{setlocale()}) and UTF-16 encoding are supported.
 
@@ -244,24 +252,123 @@ There is fast evaluation of a textual mathematical expression. It is based on st
 @node Pictures, MGL scripts, Features, Top
 @section Pictures
 
+There are samples for @ref{1D plotting, 1D arrays}, @ref{2D plotting, 2D arrays}, @ref{3D plotting, 3D arrays}, @ref{Vector fields} and some @ref{Extra samples}.
+
 @anchor{1D plotting}
 @subsection Examples of graphics for 1d arrays
 
+@fig{plot, mathgl_en/mathgl_en_13.html#Plot-sample}
+@fig{radar, mathgl_en/mathgl_en_13.html#Radar-sample}
+@fig{step, mathgl_en/mathgl_en_13.html#Step-sample}
+@fig{tens, mathgl_en/mathgl_en_13.html#Tens-sample}
+
+@fig{area, mathgl_en/mathgl_en_13.html#Area-sample}
+@fig{region, mathgl_en/mathgl_en_13.html#Region-sample}
+@fig{stem, mathgl_en/mathgl_en_13.html#Stem-sample}
+@fig{torus, mathgl_en/mathgl_en_13.html#Torus-sample}
+
+@fig{bars, mathgl_en/mathgl_en_13.html#Bars-sample}
+@fig{barh, mathgl_en/mathgl_en_13.html#Barh-sample}
+@fig{cones, mathgl_en/mathgl_en_13.html#Cones-sample}
+@fig{chart, mathgl_en/mathgl_en_13.html#Chart-sample}
+
+@fig{boxplot, mathgl_en/mathgl_en_13.html#BoxPlot-sample}
+@fig{candle, mathgl_en/mathgl_en_13.html#Candle-sample}
+@fig{tube, mathgl_en/mathgl_en_13.html#Tube-sample}
+@fig{tape, mathgl_en/mathgl_en_13.html#Tape-sample}
+
+@fig{error, mathgl_en/mathgl_en_13.html#Error-sample}
+@fig{mark, mathgl_en/mathgl_en_13.html#Mark-sample}
+@fig{textmark, mathgl_en/mathgl_en_13.html#TextMark-sample}
+@fig{label, mathgl_en/mathgl_en_13.html#Label-sample}
+
 @anchor{2D plotting}
 @subsection Examples of graphics for 2d arrays
 
+@fig{surf, mathgl_en/mathgl_en_14.html#Surf-sample}
+@fig{surfc, mathgl_en/mathgl_en_14.html#SurfC-sample}
+@fig{surfa, mathgl_en/mathgl_en_14.html#SurfA-sample}
+@fig{mesh, mathgl_en/mathgl_en_14.html#Mesh-sample}
+
+@fig{fall, mathgl_en/mathgl_en_14.html#Fall-sample}
+@fig{belt, mathgl_en/mathgl_en_14.html#Belt-sample}
+@fig{boxs, mathgl_en/mathgl_en_14.html#Boxs-sample}
+@fig{axial, mathgl_en/mathgl_en_14.html#Axial-sample}
+
+@fig{dens, mathgl_en/mathgl_en_14.html#Dens-sample}
+@fig{tile, mathgl_en/mathgl_en_14.html#Tile-sample}
+@fig{tiles, mathgl_en/mathgl_en_14.html#TileS-sample}
+@fig{grad, mathgl_en/mathgl_en_14.html#Grad-sample}
+
+@fig{cont, mathgl_en/mathgl_en_14.html#Cont-sample}
+@fig{contf, mathgl_en/mathgl_en_14.html#ContF-sample}
+@fig{contd, mathgl_en/mathgl_en_14.html#ContD-sample}
+@fig{contv, mathgl_en/mathgl_en_14.html#ContV-sample}
+
 @anchor{3D plotting}
 @subsection Examples of graphics for 3d arrays
 
-@anchor{Dual plotting}
-@subsection Examples of graphics for several arrays
+@fig{surf3, mathgl_en/mathgl_en_15.html#Surf3-sample}
+@fig{surf3c, mathgl_en/mathgl_en_15.html#Surf3C-sample}
+@fig{surf3a, mathgl_en/mathgl_en_15.html#Surf3A-sample}
+@fig{cloud, mathgl_en/mathgl_en_15.html#Cloud-sample}
+
+@fig{densa, mathgl_en/mathgl_en_15.html#Dens3-sample}
+@fig{conta, mathgl_en/mathgl_en_15.html#Cont3-sample}
+@fig{contfa, mathgl_en/mathgl_en_15.html#ContF3-sample}
+@fig{dots, mathgl_en/mathgl_en_15.html#Dots-sample}
+
+@fig{dens_xyz, mathgl_en/mathgl_en_15.html#Dens-projection-sample}
+@fig{cont_xyz, mathgl_en/mathgl_en_15.html#Cont-projection-sample}
+@fig{contf_xyz, mathgl_en/mathgl_en_15.html#ContF-projection-sample}
+@fig{triplot, mathgl_en/mathgl_en_15.html#TriPlot-and-QuadPlot}
 
 @anchor{Vector fields}
 @subsection Examples of graphics for vector fields
 
+@fig{vect, mathgl_en/mathgl_en_16.html#Vect-sample}
+@fig{traj, mathgl_en/mathgl_en_16.html#Tra-sjample}
+@fig{flow, mathgl_en/mathgl_en_16.html#Flow-sample}
+@fig{pipe, mathgl_en/mathgl_en_16.html#Pipe-sample}
+
 @anchor{Extra samples}
 @subsection Examples of additional features
 
+@fig{inplot, mathgl_en/mathgl_en_10.html#Subplots}
+@fig{axis, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+@fig{ticks, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+@fig{loglog, mathgl_en/mathgl_en_10.html#Axis-and-ticks}
+
+@fig{curvcoor, mathgl_en/mathgl_en_10.html#Curvilinear-coordinates}
+@fig{colorbar, mathgl_en/mathgl_en_10.html#Colorbars}
+@fig{box, mathgl_en/mathgl_en_10.html#Bounding-box}
+@fig{ternary, mathgl_en/mathgl_en_10.html#Ternary-axis}
+
+@fig{text, mathgl_en/mathgl_en_10.html#Text-features}
+@fig{legend, mathgl_en/mathgl_en_10.html#Legend-sample}
+@fig{cut, mathgl_en/mathgl_en_10.html#Cutting-sample}
+@fig{alpha, mathgl_en/mathgl_en_17.html#Transparency-and-lighting}
+
+@fig{type0, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{type1, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{type2, mathgl_en/mathgl_en_17.html#Types-of-transparency}
+@fig{fog, mathgl_en/mathgl_en_17.html#Adding-fog}
+
+@fig{combined, mathgl_en/mathgl_en_17.html#g_t_0060_0060Compound_0027_0027-graphics}
+@fig{several_light, mathgl_en/mathgl_en_17.html#Several-light-sources}
+@fig{stereo, mathgl_en/mathgl_en_17.html#Stereo-image}
+@fig{primitives, mathgl_en/mathgl_en_17.html#Using-primitives}
+
+@fig{stfa, mathgl_en/mathgl_en_17.html#STFA-sample}
+@fig{dat_diff, mathgl_en/mathgl_en_11.html#Change-data}
+@fig{dat_extra, mathgl_en/mathgl_en_11.html#Change-data}
+@fig{map, mathgl_en/mathgl_en_17.html#Mapping-visualization}
+
+@fig{hist, mathgl_en/mathgl_en_17.html#Making-histogram}
+@fig{fit, mathgl_en/mathgl_en_17.html#Nonlinear-fitting-sample}
+@fig{pde, mathgl_en/mathgl_en_17.html#PDE-solving-hints}
+@fig{parser, mathgl_en/mathgl_en_17.html#MGL-parser-using}
+
 @external
 
 @node MGL scripts, Download, Pictures, Top
@@ -303,11 +410,11 @@ Before the first using all variables must be defined with the help of commands,
 
 Command may have several set of possible arguments (for example, @code{plot ydat} and @code{plot xdat ydat}). All command arguments for a selected set must be specified. However, some arguments can have default values. These argument are printed in [], like @code{text ydat ['stl'='']} or @code{text x y 'txt' ['fnt'='' size=-1]}. At this, the record @code{[arg1 arg2 arg3 ...]} means @code{[arg1 [arg2 [arg3 ...]]]}, i.e. you can omit only tailing arguments if you agree with its default values. For example, @code{text x y 'txt' '' 1} or @code{text x y 'txt' ''} is correct, but @code{text x y 'txt' 1} is incorrect (argument @code{'fnt'} is missed).
 
-For more details see @uref{TODO, MathGL documentation}
+For more details see @uref{../mathgl_en/mathgl_en_64.html#MGL-scripts, MathGL documentation}
 
 @external
 
-@node Download, Documentation, MGL scripts, Top
+@node Download, Other projects, MGL scripts, Top
 @section Download
 
 @strong{Stable version (v.2.0)}
@@ -378,18 +485,7 @@ There are a set of @uref{http://sourceforge.net/project/showfiles.php?group_id=1
 
 @external
 
-@node Documentation, Other projects, Download, Top
-@section Documentation
-
-Here you can view and download latest version of documentation. This documentation is just compiled version of @uref{https://sourceforge.net/svn/?group_id=152187,SVN} documentation.
-
-There are @uref{TODO,English} and @uref{TODO,Russian} versions. It also include @uref{TODO,FAQ} about MathGL.
-
-Another variant is download single @uref{mathgl_en.pdf,PDF} (about 7 Mb).
-
-@external
-
-@node Other projects, , Documentation, Top
+@node Other projects, , Download, Top
 @section Other projects
 
 Except scientific (non public) projects I also have some general interest projects:
index 063d0bf2f82b0f4701ae875110bd207ed3499da8..4317654da7184cea8105c7a1e770c19d278b181a 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -4,6 +4,7 @@ Device 0 (VID=0502 and PID=337d) is UNKNOWN.
 ============= NEW  =============
 
 2. Add help about cmake into the "Installation and using" -- after build system will be ready
+3. Add FAQ about MPEG/GIF and PDF
 
 4. Check RunThr() in python
 
@@ -38,6 +39,10 @@ Device 0 (VID=0502 and PID=337d) is UNKNOWN.
 24. Use OI & Z for determining {x,y,z} from {xs,ys}. Try to find closest.
 25. More accurate intersections in Region
 26. Add flag for drawing 3d arrows instead of 2d (S,D -- cube, T -- sq.pyramid, I -- square, O -- sphere???, A,K,V -- ???)
+27. s_hull for triangulation -- add define for any cerr (or exclude streams
+at all) + testing
+28. Add extra texture in Error -- for handling transparency of "marks"
+29. Textual colors, like "{0xFF00FF}" ?!?
 
 ============= UDAV =============
 
index 0dce80935d3a110f0e0240ffd3fdebcb9dbe4965..0543b6ce4b3e58745c2c29f5146c175a043b1066 100644 (file)
@@ -378,6 +378,41 @@ void mgl_export_eps_cb(Fl_Widget*, void* v)
        mgl_write_eps(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
 }
 //-----------------------------------------------------------------------------
+void mgl_export_prc_cb(Fl_Widget*, void* v)
+{
+       char *fname = fl_file_chooser(gettext("Save File As?"), "*.prc", 0);
+       if(!fname || !fname[0]) return;
+       mgl_write_prc(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
+}
+//-----------------------------------------------------------------------------
+void mgl_export_tex_cb(Fl_Widget*, void* v)
+{
+       char *fname = fl_file_chooser(gettext("Save File As?"), "*.tex", 0);
+       if(!fname || !fname[0]) return;
+       mgl_write_tex(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
+}
+//-----------------------------------------------------------------------------
+void mgl_export_obj_cb(Fl_Widget*, void* v)
+{
+       char *fname = fl_file_chooser(gettext("Save File As?"), "*.obj", 0);
+       if(!fname || !fname[0]) return;
+       mgl_write_obj(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,1);
+}
+//-----------------------------------------------------------------------------
+void mgl_export_off_cb(Fl_Widget*, void* v)
+{
+       char *fname = fl_file_chooser(gettext("Save File As?"), "*.off", 0);
+       if(!fname || !fname[0]) return;
+       mgl_write_off(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0,0);
+}
+//-----------------------------------------------------------------------------
+void mgl_export_stl_cb(Fl_Widget*, void* v)
+{
+       char *fname = fl_file_chooser(gettext("Save File As?"), "*.stl", 0);
+       if(!fname || !fname[0]) return;
+       mgl_write_stl(((Fl_MGLView*)v)->FMGL->get_graph(),fname,0);
+}
+//-----------------------------------------------------------------------------
 void mgl_su_cb(Fl_Widget*, void* v)
 {
        Fl_MGLView *e = (Fl_MGLView*)v; if(!e)  return;
@@ -471,7 +506,7 @@ void mgl_sshow_cb(Fl_Widget *, void *v)
 void mglCanvasFL::Animation()  {       Fl::lock();     mgl_sshow_cb(0,mgl);    Fl::unlock();   }
 void mgl_no_cb(Fl_Widget *, void *)    {}
 //-----------------------------------------------------------------------------
-Fl_Menu_Item pop_graph[15] = {
+Fl_Menu_Item pop_graph[20] = {
        { gettext("Export"), 0, mgl_no_cb, 0, FL_SUBMENU,0,0,0,0},
                { gettext("... as PNG"),        0, mgl_export_png_cb,0,0,0,0,0,0 },
                { gettext("... as PNG (solid)"),        0, mgl_export_pngn_cb,0,0,0,0,0,0 },
@@ -479,6 +514,11 @@ Fl_Menu_Item pop_graph[15] = {
                { gettext("... as SVG"),        0, mgl_export_svg_cb,0,0,0,0,0,0 },
                { gettext("... as vector EPS"), 0, mgl_export_eps_cb,0,0,0,0,0,0 },
                { gettext("... as bitmap EPS"), 0, mgl_export_bps_cb, 0, FL_MENU_DIVIDER,0,0,0,0 },
+               { gettext("... as TeX"),        0, mgl_export_tex_cb,0,0,0,0,0,0 },
+               { gettext("... as OBJ"),        0, mgl_export_obj_cb,0,0,0,0,0,0 },
+               { gettext("... as PRC"),        0, mgl_export_prc_cb,0,0,0,0,0,0 },
+               { gettext("... as OFF"),        0, mgl_export_off_cb,0,0,0,0,0,0 },
+               { gettext("... as STL"),        0, mgl_export_stl_cb,0,0,0,0,0,0 },
                { 0,0,0,0,0,0,0,0,0 },
        { gettext("Copy graphics"),     0, 0, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER,0,0,0,0},
        { gettext("Normal view"),       0, mgl_norm_cb,0,0,0,0,0,0 },
index 8d27c466f7ee4075ecb019637cda81dd61aafed1..e67010047ecb5e88bd5ef160668abe03ea2dc44d 100644 (file)
@@ -385,7 +385,7 @@ void QMathGL::exportXYZ(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_xyz(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_xyz(gr,setExtension(fname,"xyz").toAscii(), appName.toAscii());
                setlocale(LC_NUMERIC, "");
        }
 }
@@ -397,7 +397,7 @@ void QMathGL::exportTEX(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_tex(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_tex(gr,setExtension(fname,"tex").toAscii(), appName.toAscii());
                setlocale(LC_NUMERIC, "");
        }
 }
@@ -409,7 +409,7 @@ void QMathGL::exportOFF(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_off(gr,setExtension(fname,"svg").toAscii(), appName.toAscii(),0);
+               mgl_write_off(gr,setExtension(fname,"off").toAscii(), appName.toAscii(),0);
                setlocale(LC_NUMERIC, "");
        }
 }
@@ -421,7 +421,7 @@ void QMathGL::exportOBJ(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_obj(gr,setExtension(fname,"svg").toAscii(), appName.toAscii(),0);
+               mgl_write_obj(gr,setExtension(fname,"obj").toAscii(), appName.toAscii(),0);
                setlocale(LC_NUMERIC, "");
        }
 }
@@ -433,7 +433,7 @@ void QMathGL::exportSTL(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_stl(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_stl(gr,setExtension(fname,"stl").toAscii(), appName.toAscii());
                setlocale(LC_NUMERIC, "");
        }
 }
@@ -445,7 +445,7 @@ void QMathGL::exportSTL(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_x3d(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_x3d(gr,setExtension(fname,"x3d").toAscii(), appName.toAscii());
                setlocale(LC_NUMERIC, "");
        }
 }*/
@@ -457,19 +457,19 @@ void QMathGL::exportTGA(QString fname)
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_tga(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_tga(gr,setExtension(fname,"tga").toAscii(), appName.toAscii());
                setlocale(LC_NUMERIC, "");
        }
 }
 //-----------------------------------------------------------------------------
-void QMathGL::exportIDTF(QString fname)
+void QMathGL::exportPRC(QString fname)
 {
        if(fname.isEmpty())     fname = gr->PlotId.c_str();
        if(fname.isEmpty())     QMessageBox::critical(this, appName, tr("No filename."),QMessageBox::Ok,0,0);
        else
        {
                setlocale(LC_NUMERIC, "C");
-               mgl_write_idtf(gr,setExtension(fname,"svg").toAscii(), appName.toAscii());
+               mgl_write_prc(gr,setExtension(fname,"prc").toAscii(), appName.toAscii(),1);
                setlocale(LC_NUMERIC, "");
        }
 }