DataPlot.cpp

Go to the documentation of this file.
00001 //DataPlot.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // GreyLabWindow
00006 //
00007 // Data plotting routines for the GreyLabWindow class
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.29 - 2008/03/10 - Changes to allow export of all linescans
00012 // v 1.28 - 2007/12/13 - More z-axis plotting options
00013 // v 1.27 - 2007/12/07 - Re-labelled some widgets
00014 // v 1.26 - 2007/11/30 - Diagonal tick for trace legend
00015 // v 1.25 - 2007/08/16 - Colour linescans using colour ramp
00016 // v 1.24 - 2007/06/12 - 2.17.2 improvements
00017 // v 1.23 - 2007/05/31 - Linescan fixes
00018 // v 1.22 - 2007/04/04 - Improvements to plot outputs
00019 // v 1.21 - 2007/04/01 - Changes to turning gradient related bits off and part redraws for speed
00020 // v 1.20 - 2007/03/27 - Fixed font AA
00021 // v 1.19 - 2007/03/23 - Changes to linescan offsets, better font AA
00022 // v 1.18 - 2007/03/14 - Turn titles on and off and positioning refinements
00023 // v 1.17 - 2007/02/17 - Linescan range plotting
00024 // v 1.16 - 2007/02/06 - Stroked AA lines
00025 // v 1.15 - 2007/02/01 - Refined hi-res output
00026 // v 1.14 - 2007/01/15 - Fixed 'drawObjects' so it is before image conversion
00027 // v 1.13 - 2007/01/06 - Changes for 2.11.0
00028 // v 1.12 - 2006/11/19 - Changes for 2.10.2
00029 // v 1.11 - 2006/11/19 - Changed offset to absolute and fixed
00030 // v 1.10 - 2006/11/18 - Lots of changes for 2.10.0
00031 // v 1.9 - 2006/11/14 - Fixed some bugs I introduced in 2.9.0
00032 // v 1.8 - 2006/11/13 - Export all columns options
00033 // v 1.7 - 2006/09/09 - Reverse draw order option on linescan
00034 // v 1.6 - 2006/09/07 - Fixed crash when the title overwrites the end of the array
00035 // v 1.5 - 2006/08/28 - Colourscale interpolation (2.8.0)
00036 // v 1.4 - 2006/08/28 - Moved a few functions around
00037 // v 1.3 - 2006/08/27 - Lots of changes, mostly to drawing linescans
00038 // v 1.2 - 2006/07/07 - Additions and fixes (v2.1.0)
00039 // v 1.1 - 2006/04/25 - Fixed inconsistent clipping of colours on exact range limit
00040 // v 1.0 - 2006/04/19 - Initial release
00041 //
00042 // See LICENSE.txt for distribution and usage restrictions
00043 // Copyright (c) 2005-2007 Simon Chorley
00044 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00045 //
00046 /*************************************************************/
00047 
00048 
00049 ///Data plotting functions
00050 /**
00051  * Provides implementation of GreyLabWindow functions to plot the data.
00052  * @file DataPlot.cpp
00053  * @version 1.29 - 2008/03/10
00054  */
00055 
00056 
00057 #include "GreyLab.h"
00058 
00059 
00060 #include <fstream>
00061 #include <iostream>
00062 //#include <stdio.h>
00063 #include <ctime>
00064 
00065 #include "aaLine.h"
00066 #include "Vector.h"
00067 
00068 
00069 //#define COPY(d, s) { finalimage[0+3*(d)] = FXREDVAL(strdata[s]); finalimage[1+3*(d)] = FXGREENVAL(strdata[s]); finalimage[2+3*(d)] = FXBLUEVAL(strdata[s]); }
00070 //#define COPYL(d, s) { finallineimage[0+3*(d)] = FXREDVAL(strdata[s]); finallineimage[1+3*(d)] = FXGREENVAL(strdata[s]); finallineimage[2+3*(d)] = FXBLUEVAL(strdata[s]); }
00071 /*#define COPY(d, s) { float a = (255.0-(float)FXREDVAL(strdata[s]))/255.0; \
00072         finalimage[0+3*(d)] = (char)(a*FXREDVAL(strdata[s])+(1.0-a)*finalimage[0+3*(d)]); \
00073         finalimage[1+3*(d)] = (char)(a*FXGREENVAL(strdata[s])+(1.0-a)*finalimage[1+3*(d)]); \
00074         finalimage[2+3*(d)] = (char)(a*FXBLUEVAL(strdata[s])+(1.0-a)*finalimage[2+3*(d)]); }
00075 #define COPYL(d, s) { float a = (255.0-(float)FXREDVAL(strdata[s]))/255.0; \
00076         finallineimage[0+3*(d)] = (char)(a*FXREDVAL(strdata[s])+(1.0-a)*finallineimage[0+3*(d)]); \
00077         finallineimage[1+3*(d)] = (char)(a*FXGREENVAL(strdata[s])+(1.0-a)*finallineimage[1+3*(d)]); \
00078         finallineimage[2+3*(d)] = (char)(a*FXBLUEVAL(strdata[s])+(1.0-a)*finallineimage[2+3*(d)]); }*/
00079 #define COPY(d, s) { float a = (255.0-(float)FXREDVAL(strdata[s]))/255.0; \
00080         finalimage[0+3*(d)] = (char)(a+(1.0-a)*finalimage[0+3*(d)]); \
00081         finalimage[1+3*(d)] = (char)(a+(1.0-a)*finalimage[1+3*(d)]); \
00082         finalimage[2+3*(d)] = (char)(a+(1.0-a)*finalimage[2+3*(d)]); }
00083 #define COPYL(d, s) { float a = (255.0-(float)FXREDVAL(strdata[s]))/255.0; \
00084         finallineimage[0+3*(d)] = (char)(a+(1.0-a)*finallineimage[0+3*(d)]); \
00085         finallineimage[1+3*(d)] = (char)(a+(1.0-a)*finallineimage[1+3*(d)]); \
00086         finallineimage[2+3*(d)] = (char)(a+(1.0-a)*finallineimage[2+3*(d)]); }
00087 
00088 ///Recalculates colourscale image data
00089 /**
00090  * Recalculates the data needed for rendering the colourscale image. All parameters are unused.
00091  */
00092 long GreyLabWindow::cmdGSRecalc(FXObject* o, FXSelector, void*)
00093 {
00094         if (pdata.validdata != true) return(1);
00095         gsinfo.validdata = false;
00096         
00097         unsigned int i, j, m, n, k;
00098         float xpt, ypt;
00099         float dx = 1e10;
00100         float dy = 1e10;
00101 
00102         //get image and data limits
00103 #ifdef WIN32
00104         gsinfo.xpixels = FXFloatVal(gsxresTextfield->getText());
00105         gsinfo.ypixels = FXFloatVal(gsyresTextfield->getText());
00106 #else
00107         gsinfo.xpixels = FXLongVal(gsxresTextfield->getText());
00108         gsinfo.ypixels = FXLongVal(gsyresTextfield->getText());
00109 #endif
00110 
00111         gsinfo.xstart = FXFloatVal(gsxminTextfield->getText());
00112         gsinfo.xend = FXFloatVal(gsxmaxTextfield->getText());
00113         gsinfo.ystart = FXFloatVal(gsyminTextfield->getText());
00114         gsinfo.yend = FXFloatVal(gsymaxTextfield->getText());
00115         float xdelta = (gsinfo.xend-gsinfo.xstart)/(float)(gsinfo.xpixels-1);
00116         float ydelta = (gsinfo.yend-gsinfo.ystart)/(float)(gsinfo.ypixels-1);
00117 
00118         if (gsdata != NULL)
00119                 delete[] gsdata;
00120         gsdata = new point[gsinfo.xpixels*gsinfo.ypixels];
00121         if (gscolumns != NULL)
00122                 delete[] gscolumns;
00123         gscolumns = new double[gsinfo.xpixels*gsinfo.ypixels*sdinfo.ncols];
00124 
00125         //create data array
00126         for (i = 0; i < gsinfo.xpixels*gsinfo.ypixels; ++i)
00127         {
00128                 gsdata[i].data = 0.0;
00129                 gsdata[i].n = 0;
00130                 for (j = 0; j < sdinfo.ncols; ++j)
00131                         gscolumns[i*sdinfo.ncols+j] = 0.0;
00132         }
00133         
00134         double px, py;
00135         FXApp *a = getApp();
00136         if (dascatterCheckbutton->getCheck() == false)
00137         {
00138                 statusProgressbar->setTotal(gsinfo.xpixels);
00139                 bool xfound, yfound;
00140                 for (i = 0; i < gsinfo.xpixels; ++i)
00141                 {
00142                         xpt = (float)i*xdelta+gsinfo.xstart;    //center of x pixel
00143                         for (j = 0; j < gsinfo.ypixels; ++j)
00144                         {
00145                                 xfound = false;
00146                                 yfound = false;
00147                                 ypt = (float)j*ydelta+gsinfo.ystart;    //center of y pixel
00148                                 for (n = 0; n < pdata.ny; ++n)
00149                                 {
00150                                         if (n != pdata.ny-1)    //don't update dy if at last point (we can't calculate a proper dy since it's the last point, so we guess instead)
00151                                                 dy = pdata.y[n+1]-pdata.y[n];
00152 //                                      cerr << "ypt" << ypt << " yd" << pdata.y[n] << "," << pdata.y[n+1] << '\n';
00153                                         if (((ypt >= pdata.y[n]) && (ypt < pdata.y[n]+dy)) || ((ypt < pdata.y[n]) && (ypt >= pdata.y[n]+dy)))
00154                                         {
00155 //                                              cerr << '.';
00156                                                 yfound = true;
00157                                                 break;
00158                                         }
00159                                 }
00160 //                              cerr << "*\n";
00161                                 for (m = 0; m < pdata.nx; ++m)
00162                                 {
00163                                         if (m != pdata.nx-1)    //don't update dx if at last point
00164                                                 dx = pdata.x[m+1]-pdata.x[m];
00165 ///                                     cerr << "xpt" << xpt << " xd" << pdata.x[m] << "," << pdata.x[m+1] << '\n';
00166                                         if (((xpt >= pdata.x[m]) && (xpt < pdata.x[m]+dx)) || ((xpt < pdata.x[m]) && (xpt >= pdata.x[m]+dx)))
00167                                         {
00168                                                 xfound = true;
00169                                                 break;
00170                                         }
00171                                 }
00172 //                              cerr << "!\n";
00173                                 if ((xfound == true) && (yfound == true))
00174                                 {
00175                                         if (pdata.z[n][m].n > 0)
00176                                         {
00177                                                 if ((gsxinterpCheckbutton->getCheck() == true) && (gsyinterpCheckbutton->getCheck() == true))   //interpolate both
00178                                                 {
00179                                                         double a1, a2;
00180                                                         double py = (pdata.y[n]-ypt)/dy;
00181                                                         if (py >= 0.0)
00182                                                         {
00183                                                                 if (n > 0)
00184                                                                         a1 = (1.0-py)*pdata.z[n][m].data+py*pdata.z[n-1][m].data;
00185                                                                 else
00186                                                                         a1 = pdata.z[n][m].data;
00187                                                         }
00188                                                         else
00189                                                         {
00190                                                                 if (n < (pdata.ny-1))
00191                                                                         a1 = (1.0+py)*pdata.z[n][m].data-py*pdata.z[n+1][m].data;
00192                                                                 else
00193                                                                         a1 = pdata.z[n][m].data;
00194                                                         }
00195                                                         double px = (pdata.x[m]-xpt)/dx;
00196                                                         if (px >= 0.0)
00197                                                         {
00198                                                                 if (m > 0)              //changed 2007/01/05 to try to fix crash
00199                 //                                              if (m-1 > 0)
00200                                                                 {
00201                                                                         if (py >= 0.0)
00202                                                                         {
00203                                                                                 if (n > 0)
00204                                                                                         a2 = (1.0-py)*pdata.z[n][m-1].data+py*pdata.z[n-1][m-1].data;
00205                                                                                 else
00206                                                                                         a2 = pdata.z[n][m-1].data;
00207                                                                         }
00208                                                                         else
00209                                                                         {
00210                                                                                 if (n < (pdata.ny-1))
00211                                                                                         a2 = (1.0+py)*pdata.z[n][m-1].data-py*pdata.z[n+1][m-1].data;
00212                                                                                 else
00213                                                                                         a2 = pdata.z[n][m-1].data;
00214                                                                         }
00215                                                                 }
00216                                                                 else
00217                                                                         a2 = pdata.z[n][m].data;
00218                                                         }
00219                                                         else
00220                                                         {
00221                                                                 if (m < (pdata.nx-1))           //changed 2007/01/05 to try to fix crash
00222                 //                                              if (m+1 < (pdata.nx-1))
00223                                                                 {
00224                                                                         if (py >= 0.0)
00225                                                                         {
00226                                                                                 if (n > 0)
00227                                                                                         a2 = (1.0-py)*pdata.z[n][m+1].data+py*pdata.z[n-1][m+1].data;
00228                                                                                 else
00229                                                                                         a2 = pdata.z[n][m+1].data;
00230                                                                         }
00231                                                                         else
00232                                                                         {
00233                                                                                 if (n < (pdata.ny-1))
00234                                                                                         a2 = (1.0+py)*pdata.z[n][m+1].data-py*pdata.z[n+1][m+1].data;
00235                                                                                 else
00236                                                                                         a2 = pdata.z[n][m+1].data;
00237                                                                         }
00238                                                                 }
00239                                                                 else
00240                                                                         a2 = pdata.z[n][m].data;
00241                                                         }
00242                                                         if (px >= 0.0)
00243                                                                 gsdata[i+gsinfo.xpixels*j].data = (1.0-px)*a1+px*a2;
00244                                                         else
00245                                                                 gsdata[i+gsinfo.xpixels*j].data = (1.0+px)*a1-px*a2;
00246                                                         gsdata[i+gsinfo.xpixels*j].n = 1;
00247                                                 }
00248                                                 else if (gsyinterpCheckbutton->getCheck() == true)      //interpolate y only
00249                                                 {
00250                                                         double py = (pdata.y[n]-ypt)/dy;
00251                                                         if (py >= 0.0)
00252                                                         {
00253                                                                 if (n > 0)
00254                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0-py)*pdata.z[n][m].data+py*pdata.z[n-1][m].data;
00255                                                                 else
00256                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00257                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00258                                                         }
00259                                                         else
00260                                                         {
00261                                                                 if (n < (pdata.ny-1))
00262                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0+py)*pdata.z[n][m].data-py*pdata.z[n+1][m].data;
00263                                                                 else
00264                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00265                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00266                                                         }
00267                                                 }
00268                                                 else if (gsxinterpCheckbutton->getCheck() == true)      //interpolate x only
00269                                                 {
00270                                                         double px = (pdata.x[m]-xpt)/dx;
00271                                                         if (px >= 0.0)
00272                                                         {
00273                                                                 if (m > 0)
00274                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0-px)*pdata.z[n][m].data+px*pdata.z[n][m-1].data;
00275                                                                 else
00276                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00277                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00278                                                         }
00279                                                         else
00280                                                         {
00281                                                                 if (m < (pdata.nx-1))
00282                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0+px)*pdata.z[n][m].data-px*pdata.z[n][m+1].data;
00283                                                                 else
00284                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00285                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00286                                                         }
00287                                                 }
00288                                                 else
00289                                                 {
00290                                                         gsdata[i+gsinfo.xpixels*j].data += pdata.z[n][m].data;
00291 //                                                      ++gsdata[i+gsinfo.xpixels*j].n; //was ++, not sure why?
00292                                                         gsdata[i+gsinfo.xpixels*j].n = 1;       //was ++, not sure why?
00293                                                 }
00294                                                 for (k = 0; k < sdinfo.ncols; ++k)
00295                                                         gscolumns[j*gsinfo.xpixels*sdinfo.ncols+i*sdinfo.ncols+k] = pdata.columns[n*sdinfo.ncols*pdata.nx+m*sdinfo.ncols+k];
00296                                         }                                                               
00297                                 }
00298                         }
00299                         statusProgressbar->setProgress(i+1);
00300                         a->forceRefresh();
00301                         a->repaint();
00302                 }
00303         }
00304         else
00305         {
00306                 statusProgressbar->setTotal(gsinfo.xpixels);
00307                 bool xfound, yfound;
00308                 for (i = 0; i < gsinfo.xpixels; ++i)
00309                 {
00310                         dx = 0.0; dy = 0.0;
00311                         xpt = (float)i*xdelta+gsinfo.xstart;    //center of x pixel
00312                         for (j = 0; j < gsinfo.ypixels; ++j)
00313                         {
00314                                 xfound = false;
00315                                 yfound = false;
00316                                 for (m = 0; m < pdata.nx; ++m)
00317                                 {
00318                                         if (m != pdata.nx-1)    //don't update dx if at last point
00319                                                 dx = pdata.x[m+1]-pdata.x[m];
00320                                         px = pdata.x[m];
00321                                         if (((xpt >= px) && (xpt < px+dx)) || ((xpt < px) && (xpt >= px+dx)))
00322                                         {
00323                                                 xfound = true;
00324                                                 break;
00325                                         }
00326                                 }
00327                                 ypt = (float)j*ydelta+gsinfo.ystart;    //center of y pixel
00328                                 for (n = 0; n < pdata.ny; ++n)
00329                                 {
00330                                         if (pdata.z[n][m].n > 0)
00331                                         {
00332                                                 if (n != pdata.ny-1)    //don't update dy if at last point (we can't calculate a proper dy since it's the last point, so we guess instead)
00333                                                         if (pdata.z[n+1][m].n > 0)
00334                                                                 dy = pdata.scattery[n+1][m]-pdata.scattery[n][m];
00335                                                 py = pdata.scattery[n][m];
00336                                                 if (((ypt >= py) && (ypt < py+dy)) || ((ypt < py) && (ypt >= py+dy)))
00337                                                 {
00338                                                         yfound = true;
00339                                                         break;
00340                                                 }
00341                                         }
00342                                 }
00343                                 if ((xfound == true) && (yfound == true))
00344                                 {
00345                                         if (pdata.z[n][m].n > 0)
00346                                         {
00347                                                 if (gsyinterpCheckbutton->getCheck() == true)   //interpolate y only
00348                                                 {
00349                                                         double py = (pdata.scattery[n][m]-ypt)/dy;
00350                                                         if (py >= 0.0)
00351                                                         {
00352                                                                 if (n > 0)
00353                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0-py)*pdata.z[n][m].data+py*pdata.z[n-1][m].data;
00354                                                                 else
00355                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00356                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00357                                                         }
00358                                                         else
00359                                                         {
00360                                                                 if (n < (pdata.ny-1))
00361                                                                         gsdata[i+gsinfo.xpixels*j].data = (1.0+py)*pdata.z[n][m].data-py*pdata.z[n+1][m].data;
00362                                                                 else
00363                                                                         gsdata[i+gsinfo.xpixels*j].data = pdata.z[n][m].data;
00364                                                                 gsdata[i+gsinfo.xpixels*j].n = 1;
00365                                                         }
00366                                                 }
00367                                                 else
00368                                                 {
00369                                                         gsdata[i+gsinfo.xpixels*j].data += pdata.z[n][m].data;
00370                                                         ++gsdata[i+gsinfo.xpixels*j].n;
00371                                                 }
00372                                         }                                                               
00373                                 }
00374                         }
00375                         statusProgressbar->setProgress(i+1);
00376                         a->forceRefresh();
00377                         a->repaint();
00378                 }
00379         }
00380         statusProgressbar->setProgress(0);
00381 
00382         gsinfo.zlo = 1e10;
00383         gsinfo.zhi = -1e10;
00384         for (i = 0; i < gsinfo.xpixels; ++i)
00385                 for (j = 0; j < gsinfo.ypixels; ++j)
00386                 {
00387                         gsdata[i+gsinfo.xpixels*j].data /= gsdata[i+gsinfo.xpixels*j].n;
00388                         if (gsdata[i+gsinfo.xpixels*j].n > 0)
00389                         {
00390                                 if ((gsdata[i+gsinfo.xpixels*j].data > -1e10) && (gsdata[i+gsinfo.xpixels*j].data < 1e10))
00391                                 {
00392                                         if (gsdata[i+gsinfo.xpixels*j].data > gsinfo.zhi) gsinfo.zhi = gsdata[i+gsinfo.xpixels*j].data; //record range for later auto ranging
00393                                         if (gsdata[i+gsinfo.xpixels*j].data < gsinfo.zlo) gsinfo.zlo = gsdata[i+gsinfo.xpixels*j].data;
00394                                 }
00395                         }
00396 //                      cerr << gsdata[i+gsinfo.xpixels*j].data << ',';
00397                         for (k = 0; k < sdinfo.ncols; ++k)      //average columns
00398                                 gscolumns[i*sdinfo.ncols+gsinfo.xpixels*sdinfo.ncols*j+k] /= gsdata[i+gsinfo.xpixels*j].n;
00399                 }
00400 
00401         gsinfo.validdata = true;        //we now have valid data so we can make some images
00402         return(1);
00403 }
00404 
00405 
00406 ///Redraws the colourscale image
00407 /**
00408  * Renders the colourscale graph and drawing primatives and puts the result in GreyLabWindow::img.
00409  * @remark Sets GreyLabWindow::gsinfo#validimage to true on success.
00410  * @param o Calling object.
00411  * @param s Calling message type and ID.
00412  * @return Returns 1 to show the message has been handled.
00413  */
00414 long GreyLabWindow::cmdGSRedraw(FXObject* o, FXSelector s, void*)
00415 {
00416         int i, j;
00417         int xPel, yPel;
00418         double xp, yp;
00419 
00420         if (gsinfo.validdata != true) return(1);
00421         gsinfo.validimage = false;
00422 
00423         bool dofullupdate = true;
00424         if ((o == NULL) && (s == 1))
00425                 dofullupdate = false;
00426 
00427         if ((setfocusCheckbutton->getCheck() == true) && (dofullupdate == true))
00428         {
00429                 datawin->setFocus();
00430                 this->setFocus();
00431         }
00432 
00433         cmdGSUpdateGradient(NULL, 0, NULL);     //update displayed numbers
00434         float gamma = FXFloatVal(gsgammaTextfield->getText());
00435 
00436         //Generate colours
00437         FXColor colours[COLOURRES];
00438         zgradGradient->gradient(colours, COLOURRES);
00439         FXColor col;
00440         FXColor lowcol = lcolColourwell->getRGBA();
00441         FXColor hicol = hcolColourwell->getRGBA();
00442         FXColor nocol = nodataColourwell->getRGBA();
00443         unsigned char lc[3], hc[3], nc[3];
00444         lc[0] = (unsigned char)FXREDVAL(lowcol);
00445         lc[1] = (unsigned char)FXGREENVAL(lowcol);
00446         lc[2] = (unsigned char)FXBLUEVAL(lowcol);
00447         hc[0] = (unsigned char)FXREDVAL(hicol);
00448         hc[1] = (unsigned char)FXGREENVAL(hicol);
00449         hc[2] = (unsigned char)FXBLUEVAL(hicol);
00450         nc[0] = (unsigned char)FXREDVAL(nocol);
00451         nc[1] = (unsigned char)FXGREENVAL(nocol);
00452         nc[2] = (unsigned char)FXBLUEVAL(nocol);
00453 
00454         float lz = FXFloatVal(gszminTextfield->getText());
00455         float hz = FXFloatVal(gszmaxTextfield->getText());
00456 
00457         //colour data points
00458         double zdelta = FXDoubleVal(gscontourspaceTextfield->getText());
00459         unsigned char *byteimage = new unsigned char[gsinfo.xpixels*gsinfo.ypixels*3];
00460         if ((gscontourCheckbutton->getCheck() == true) && (zdelta != 0.0))
00461         {
00462                 if ((hz-lz)/zdelta > 100.0)
00463                         if (FXMessageBox::question(this, FX::MBOX_YES_NO, "Countour spacing!", ("Really plot ~"+FXStringVal((hz-lz)/zdelta)+" contours?").text()) != MBOX_CLICKED_YES)
00464                                 gscontourCheckbutton->setCheck(false);
00465         }
00466         if ((gscontourCheckbutton->getCheck() == true) && (zdelta != 0.0))
00467         {
00468                 unsigned char *cmap = new unsigned char[gsinfo.xpixels*gsinfo.ypixels*2];
00469                 memset(cmap, 0, gsinfo.xpixels*gsinfo.ypixels*2);
00470                 FXColor contourcol = gscontourcolColourwell->getRGBA();
00471                 bool altcontour = gscontouraltCheckbutton->getCheck();
00472                 //Fill in the contours
00473                 yp = zdelta*(int)(lz/zdelta)-zdelta;
00474                 for (i = 0; i < 2+(int)((hz-lz)/zdelta); ++i)
00475                 {
00476                         if ((yp >= lz) && (yp <= hz))
00477                         {
00478                                 for (yPel = 0; yPel < gsinfo.ypixels-1; ++yPel)
00479                                 {
00480                                         for (xPel = 0; xPel < gsinfo.xpixels-1; ++xPel)
00481                                         {
00482                                                 if (gsdata[xPel+gsinfo.xpixels*yPel].n > 0)
00483                                                 {
00484                                                         if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data > yp))
00485                                                                 || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+1+gsinfo.xpixels*yPel].data <= yp)))
00486                                                         {
00487                                                                 cmap[0+2*(xPel+gsinfo.xpixels*yPel)] = 255;
00488                                                                 cmap[1+2*(xPel+gsinfo.xpixels*yPel)] = 1;
00489                                                         }
00490                                                         else if (((gsdata[xPel+gsinfo.xpixels*yPel].data <= yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data > yp))
00491                                                                 || ((gsdata[xPel+gsinfo.xpixels*yPel].data > yp) && (gsdata[xPel+gsinfo.xpixels*(yPel+1)].data <= yp)))
00492                                                         {
00493                                                                 cmap[0+2*(xPel+gsinfo.xpixels*yPel)] = 255;
00494                                                                 cmap[1+2*(xPel+gsinfo.xpixels*yPel)] = 1;
00495                                                         }
00496                                                 }
00497                                         }
00498                                 }
00499                         }
00500                         yp += zdelta;
00501                 }
00502                 //Antialias corners
00503                 for (yPel = 1; yPel < gsinfo.ypixels-1; ++yPel)
00504                 {
00505                         for (xPel = 1; xPel < gsinfo.xpixels-1; ++xPel)
00506                         {
00507                                 if (cmap[1+2*(xPel+gsinfo.xpixels*yPel)] == 1)