Main Page   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

MDITwoLevel.cpp

00001 //---------------------------------------------------------------------------
00002 
00003 #include <vcl.h>
00004 #pragma hdrstop
00005 
00006 #include "MDITwoLevel.h"
00007 #include "MDIEdit.h"
00008 #include "MDIFrame.h"
00009 #include <iostream>
00010 #include <winbase.h>
00011 //---------------------------------------------------------------------------
00012 #pragma package(smart_init)
00013 #pragma resource "*.dfm"
00014 TTwoLevelForm *TwoLevelForm;
00015 rgb *_picture;
00016 //---------------------------------------------------------------------------
00017 
00021 TColor RGB2TColor(rgb c)
00022 {
00023         //return (TColor)(0x01000000+c.r+(c.g<<8)+(c.b<<16));
00024         return (TColor)(c.r+(c.g<<8)+(c.b<<16));
00025 }
00026 //---------------------------------------------------------------------------
00027 
00028 __fastcall TTwoLevelForm::TTwoLevelForm(TComponent* Owner)
00029     : TForm(Owner),
00030       _formCreate(true),
00031       _rotx(0),
00032       _roty(0),
00033       _rotz(0),
00034       _lightX(0.0),
00035       _lightY(0.0),
00036       _resolution(128),
00037       _pic_size(_resolution*_resolution),
00038       _oldres(0),
00039       _traging(false),
00040       _stopIt(false),
00041       _actres(2),
00042       _actposx(0),
00043       _actposy(0),
00044       _viewx(1,0,0),
00045       _viewy(0,1,0),
00046       _viewz(0,0,1),
00047       /*
00048       _center(0,0,0),
00049       _l2(0.0),
00050       _step(0.0),
00051       _start(0,0,0),
00052       _lightPos(0,0,0),
00053       _lightDir(0,0,0),
00054       */
00055       _maxTime(1.5),
00056       _thres(1200),
00057       _ambient(1.0),
00058       _light(1.0),
00059       _firstHit(0),
00060       _alphaFH(0.9),
00061       _thresFH(1200),
00062       _MIP(0),
00063       _alphaMIP(0.9),
00064       _MIPref(2048.0),
00065       _NPR(0),
00066       _alphaNPR(0.9),
00067       _NPRpower(4),
00068       _NPRref(100.0),
00069       _Average(0),
00070       _alphaAverage(0.9),
00071       _Averageref(2048.0),
00072       _Transparent(0),
00073       _alphaTransparent(0.9)
00074 {
00075 }
00076 //---------------------------------------------------------------------------
00077 
00078 int __fastcall TTwoLevelForm::_getFirstBitIndex(int val)
00079 {
00080     _actualBit = -1;
00081     return _getNextBitIndex(val);
00082 }
00083 //---------------------------------------------------------------------------
00084 
00085 int __fastcall TTwoLevelForm::_getNextBitIndex(int val)
00086 {
00087     int res = 0;
00088     do {
00089         ++_actualBit;
00090         res = (1<<_actualBit);
00091     } while ((_actualBit<31) && !(res&val));
00092     if (res&val) return _actualBit;
00093     else     return -1;
00094 }
00095 //---------------------------------------------------------------------------
00096 
00097 inline float __fastcall TTwoLevelForm::_getValue(vectorf & v)
00098 {
00099     if (CbThreeLinear->Checked) {
00100         int X = (int)(v.X);
00101         int Y = (int)(v.Y);
00102         int Z = (int)(v.Z);
00103         int idx = X + Y*_rowsize + Z*_pagesize;
00104         float dx = v.X - X, dy = v.Y - Y, dz = v.Z - Z;
00105         float d1x = 1.0 - dx, d1y = 1.0 - dy, d1z = 1.0 - dz;
00106         float value1 = (float)data[idx]*d1x +
00107                        (float)data[idx+1]*dx;
00108         float value2 = (float)data[idx+_rowsize]*d1x +
00109                        (float)data[idx+_rowsize+1]*dx;
00110         float value3 = (float)data[idx+_pagesize+_rowsize]*d1x +
00111                        (float)data[idx+_pagesize+_rowsize+1]*dx;
00112         float value4 = (float)data[idx+_pagesize]*d1x +
00113                        (float)data[idx+_pagesize+1]*dx;
00114         float value11 = value1*(d1y) + value2*(dy);
00115         float value22 = value4*(d1y) + value3*(dy);
00116         return (value11*(d1z) + value22*(dz));
00117     } else {
00118         int X = (int)(v.X+0.5);
00119         int Y = (int)(v.Y+0.5);
00120         int Z = (int)(v.Z+0.5);
00121         return data[X + Y*_rowsize + Z*_pagesize];
00122     }
00123 }
00124 //---------------------------------------------------------------------------
00125 
00126 /*
00127  * Assuming the following situation:
00128  *
00129  *        (*) - (x+1,y+1,z+1)
00130  *        /|      /|
00131  *      (*)|--- (*)|
00132  *       | |     | |
00133  *       |(*) ---|(*)
00134  *       |/      |/
00135  *    (x,y,z) - (*)
00136  *
00137  */
00138 inline double __fastcall TTwoLevelForm::_getValue(const vectord & v)
00139 {
00140     int X = (int)(v.X);
00141     int Y = (int)(v.Y);
00142     int Z = (int)(v.Z);
00143     int idx = X + Y*_rowsize + Z*_pagesize;
00144     double dx = v.X - X, dy = v.Y - Y, dz = v.Z - Z;
00145     double d1x = 1.0 - dx, d1y = 1.0 - dy, d1z = 1.0 - dz;
00146     double value1 = (double)data[idx]*d1x +
00147                     (double)data[idx+1]*dx;
00148     double value2 = (double)data[idx+_rowsize]*d1x +
00149                     (double)data[idx+_rowsize+1]*dx;
00150     double value3 = (double)data[idx+_pagesize+_rowsize]*d1x +
00151                     (double)data[idx+_pagesize+_rowsize+1]*dx;
00152     double value4 = (double)data[idx+_pagesize]*d1x +
00153                     (double)data[idx+_pagesize+1]*dx;
00154     double value11 = value1*(d1y) + value2*(dy);
00155     double value22 = value4*(d1y) + value3*(dy);
00156     return (value11*(d1z) + value22*(dz));
00157 }
00158 //---------------------------------------------------------------------------
00159 
00160 double inline __fastcall TTwoLevelForm::_getGradLength(const vectord & v)
00161 {
00162     int X = (int)(v.X);
00163     int Y = (int)(v.Y);
00164     int Z = (int)(v.Z);
00165     int idx = X + Y*_rowsize + Z*_pagesize;
00166     double dx = v.X - X, dy = v.Y - Y, dz = v.Z - Z;
00167     double d1x = 1.0 - dx, d1y = 1.0 - dy, d1z = 1.0 - dz;
00168     double value1 = (double)absgrad[idx]*d1x +
00169                     (double)absgrad[idx+1]*dx;
00170     double value2 = (double)absgrad[idx+_rowsize]*d1x +
00171                     (double)absgrad[idx+_rowsize+1]*dx;
00172     double value3 = (double)absgrad[idx+_pagesize+_rowsize]*d1x +
00173                     (double)absgrad[idx+_pagesize+_rowsize+1]*dx;
00174     double value4 = (double)absgrad[idx+_pagesize]*d1x +
00175                     (double)absgrad[idx+_pagesize+1]*dx;
00176     double value11 = value1*(d1y) + value2*(dy);
00177     double value22 = value4*(d1y) + value3*(dy);
00178     return (value11*(d1z) + value22*(dz));
00179 }
00180 //---------------------------------------------------------------------------
00181 
00182 vectorf inline __fastcall TTwoLevelForm::_getGradient(vectorf & v)
00183 {
00184     if (CbThreeLinear->Checked) {
00185         vectorf res;
00186         int X = (int)(v.X);
00187         int Y = (int)(v.Y);
00188         int Z = (int)(v.Z);
00189         int idx = X + Y*_rowsize + Z*_pagesize;
00190         float dx = v.X - X, dy = v.Y - Y, dz = v.Z - Z;
00191         float d1x = 1.0 - dx, d1y = 1.0 - dy, d1z = 1.0 - dz;
00192         float value1 = (float)gradient[idx].x*d1x +
00193                        (float)gradient[idx+1].x*dx;
00194         float value2 = (float)gradient[idx+_rowsize].x*d1x +
00195                        (float)gradient[idx+_rowsize+1].x*dx;
00196         float value3 = (float)gradient[idx+_pagesize+_rowsize].x*d1x +
00197                        (float)gradient[idx+_pagesize+_rowsize+1].x*dx;
00198         float value4 = (float)gradient[idx+_pagesize].x*d1x +
00199                        (float)gradient[idx+_pagesize+1].x*dx;
00200         float value11 = value1*(d1y) + value2*(dy);
00201         float value22 = value4*(d1y) + value3*(dy);
00202         res.X = value11*(d1z) + value22*(dz);
00203         value1 = (float)gradient[idx].y*d1x +
00204                  (float)gradient[idx+1].y*dx;
00205         value2 = (float)gradient[idx+_rowsize].y*d1x +
00206                  (float)gradient[idx+_rowsize+1].y*dx;
00207         value3 = (float)gradient[idx+_pagesize+_rowsize].y*d1x +
00208                  (float)gradient[idx+_pagesize+_rowsize+1].y*dx;
00209         value4 = (float)gradient[idx+_pagesize].y*d1x +
00210                  (float)gradient[idx+_pagesize+1].y*dx;
00211         value11 = value1*(d1y) + value2*(dy);
00212         value22 = value4*(d1y) + value3*(dy);
00213         res.Y = value11*(d1z) + value22*(dz);
00214         value1 = (float)gradient[idx].z*d1x +
00215                  (float)gradient[idx+1].z*dx;
00216         value2 = (float)gradient[idx+_rowsize].z*d1x +
00217                  (float)gradient[idx+_rowsize+1].z*dx;
00218         value3 = (float)gradient[idx+_pagesize+_rowsize].z*d1x +
00219                  (float)gradient[idx+_pagesize+_rowsize+1].z*dx;
00220         value4 = (float)gradient[idx+_pagesize].z*d1x +
00221                  (float)gradient[idx+_pagesize+1].z*dx;
00222         value11 = value1*(d1y) + value2*(dy);
00223         value22 = value4*(d1y) + value3*(dy);
00224         res.Z = value11*(d1z) + value22*(dz);
00225         return res;
00226     } else {
00227         int X = (int)(v.X+0.5);
00228         int Y = (int)(v.Y+0.5);
00229         int Z = (int)(v.Z+0.5);
00230         int idx = X + Y*sizeX + Z*sizeX*sizeY;
00231         return vectorf(gradient[idx].x,
00232                        gradient[idx].y,
00233                        gradient[idx].z);
00234     }
00235 }
00236 //---------------------------------------------------------------------------
00237 
00238 vectord inline __fastcall TTwoLevelForm::_getGradient(vectord & v)
00239 {
00240     vectord res;
00241     int X = (int)(v.X);
00242     int Y = (int)(v.Y);
00243     int Z = (int)(v.Z);
00244     int idx = X + Y*_rowsize + Z*_pagesize;
00245     double dx = v.X - X, dy = v.Y - Y, dz = v.Z - Z;
00246     double d1x = 1.0 - dx, d1y = 1.0 - dy, d1z = 1.0 - dz;
00247     double value1 = (double)gradient[idx].x*d1x +
00248                     (double)gradient[idx+1].x*dx;
00249     double value2 = (double)gradient[idx+_rowsize].x*d1x +
00250                     (double)gradient[idx+_rowsize+1].x*dx;
00251     double value3 = (double)gradient[idx+_pagesize+_rowsize].x*d1x +
00252                     (double)gradient[idx+_pagesize+_rowsize+1].x*dx;
00253     double value4 = (double)gradient[idx+_pagesize].x*d1x +
00254                     (double)gradient[idx+_pagesize+1].x*dx;
00255     double value11 = value1*(d1y) + value2*(dy);
00256     double value22 = value4*(d1y) + value3*(dy);
00257     res.X = value11*(d1z) + value22*(dz);
00258     value1 = (double)gradient[idx].y*d1x +
00259              (double)gradient[idx+1].y*dx;
00260     value2 = (double)gradient[idx+_rowsize].y*d1x +
00261              (double)gradient[idx+_rowsize+1].y*dx;
00262     value3 = (double)gradient[idx+_pagesize+_rowsize].y*d1x +
00263              (double)gradient[idx+_pagesize+_rowsize+1].y*dx;
00264     value4 = (double)gradient[idx+_pagesize].y*d1x +
00265              (double)gradient[idx+_pagesize+1].y*dx;
00266     value11 = value1*(d1y) + value2*(dy);
00267     value22 = value4*(d1y) + value3*(dy);
00268     res.Y = value11*(d1z) + value22*(dz);
00269     value1 = (double)gradient[idx].z*d1x +
00270              (double)gradient[idx+1].z*dx;
00271     value2 = (double)gradient[idx+_rowsize].z*d1x +
00272              (double)gradient[idx+_rowsize+1].z*dx;
00273     value3 = (double)gradient[idx+_pagesize+_rowsize].z*d1x +
00274              (double)gradient[idx+_pagesize+_rowsize+1].z*dx;
00275     value4 = (double)gradient[idx+_pagesize].z*d1x +
00276              (double)gradient[idx+_pagesize+1].z*dx;
00277     value11 = value1*(d1y) + value2*(dy);
00278     value22 = value4*(d1y) + value3*(dy);
00279     res.Z = value11*(d1z) + value22*(dz);
00280     /*
00281     // X gradient component:
00282     double v1 = _getValue(v + vectord(-0.5, 0.0, 0.0));
00283     double v2 = _getValue(v + vectord( 0.5, 0.0, 0.0));
00284     res.X = v2-v1;
00285     // Y gradient component:
00286     v1 = _getValue(v + vectord( 0.0,-0.5, 0.0));
00287     v2 = _getValue(v + vectord( 0.0, 0.5, 0.0));
00288     res.Y = v2-v1;
00289     // Z gradient component:
00290     v1 = _getValue(v + vectord( 0.0, 0.0,-0.5));
00291     v2 = _getValue(v + vectord( 0.0, 0.0, 0.5));
00292     res.Z = v2-v1;
00293     */
00294     return res;
00295 }
00296 //---------------------------------------------------------------------------
00297 
00298 void inline __fastcall TTwoLevelForm::_calcColor(rgb& col,
00299                                                  vectord &normal,
00300                                                  vectord& view,
00301                                                  vectord& light)
00302 {
00303     // Ambient:
00304     double xxx = normal^view;
00305     xxx *= xxx;
00306     xxx *= xxx;
00307     col.r *= (double)_ambientCol.r/255.0*_ambient*xxx;
00308     col.g *= (double)_ambientCol.g/255.0*_ambient*xxx;
00309     col.b *= (double)_ambientCol.b/255.0*_ambient*xxx;
00310                 // Can do this without checking the result
00311                 // for >255 cause all factors are less or
00312                 // equal to one.
00313 
00314     // Specular:
00315     vectord specH = (view+light)*0.5;
00316     specH.normal();
00317     xxx = normal^specH;
00318     //if (xxx < 0.0) xxx *= -1.0;
00319     if (xxx < 0.0) xxx = 0.0;
00320 
00321     if (_sinus) {
00322         xxx = acos(xxx);
00323         if (xxx < 0.0)  xxx=0.0;
00324         if (xxx>M_PI_2) xxx=M_PI_2;
00325         xxx = 1.0-(xxx/M_PI_2);
00326     }
00327     switch (_power) {
00328         case 10: xxx *= xxx;     // 1024
00329         case  9: xxx *= xxx;     //  512
00330         case  8: xxx *= xxx;     //  256
00331         case  7: xxx *= xxx;     //  128
00332         case  6: xxx *= xxx;     //   64
00333         case  5: xxx *= xxx;     //   32
00334         case  4: xxx *= xxx;     //   16
00335         case  3: xxx *= xxx;     //    8
00336         case  2: xxx *= xxx;     //    4
00337         default: xxx *= xxx;     //    2
00338     }
00339     col += _lightCol*_light*xxx;
00340 }
00341 //---------------------------------------------------------------------------
00342 
00343 void __fastcall TTwoLevelForm::_resize()
00344 {
00345     if (_picture) delete [] _picture;
00346     _pic_size = _resolution*_resolution;
00347     _picture = new rgb[_pic_size];
00348     memusage = memusage - 3*_oldres*_oldres + 3*_pic_size;
00349     FrameForm->memupdate();
00350     LResolution->Caption = AnsiString(_resolution) +
00351                            AnsiString(" x ") +
00352                            AnsiString(_resolution);
00353 }
00354 //---------------------------------------------------------------------------
00355 
00356 void inline __fastcall TTwoLevelForm::_renderPreview()
00357 {
00358     // Reset from the last image calculation.
00359     DrawingTimer->Enabled = false;
00360     FrameForm->StatusProgress->Visible = false;
00361     FrameForm->StatusMain->Caption = "";
00362 
00363 
00364     // We assume the viewing plane lies in x-z-direction. This means:
00365     // * dragging in horizontal direction corresponds to a rotation around
00366     //   the z axis,
00367     // * dragging in vertical direction means a rotation around the x axis,
00368     // * the ray follows the y axis
00369 
00370     // Viewing direction vectors:
00371     vectorf viewx(1,0,0), viewy(0,1,0), viewz(0,0,1);
00372     // rotate them:
00373     float rrotx = _rotx * 3.14159265 / 180.0;
00374     float rrotz = _rotz * 3.14159265 / 180.0;
00375     viewx.rotx(rrotx); viewx.rotz(rrotz); viewx.normal();
00376     viewy.rotx(rrotx); viewy.rotz(rrotz); viewy.normal();
00377     viewz.rotx(rrotx); viewz.rotz(rrotz); viewz.normal();
00378     // Viewing volume center:
00379     vectorf center(sizeX/2, sizeY/2, sizeZ/2);
00380     // Distance from volume middle to an edge:
00381     float l = _dist, l2 = l*2.0;
00382     // width of one step:
00383     float step = 2*l/(float)PREVIEW_SIZE;
00384     // Start position of line:
00385     vectorf linestart = center + (viewx*(-l)) + (viewy*(-l)) + (viewz*(-l));
00386     // Start position of ray:
00387     vectorf start = linestart;
00388     // Light position:
00389     vectorf lightPos = center + (viewy*(-l))
00390                        + (viewx*_lightX) + (viewz*_lightY);
00391     // Light direction:
00392     vectorf lightDir = center - lightPos;
00393     lightDir.normal();
00394     // Actual position of ray:
00395     vectorf pos;
00396     // Last position bevor actual position of ray:
00397     vectorf oldpos;
00398     // The actual length of the ray:
00399     float raylen;
00400     // Actual data value:
00401     int val;
00402     // Actual position in data:
00403     int X, Y, Z, idx;
00404     // Inside indicator:
00405     bool inside;
00406     // step is the size of one preview pixel in the domain of the image:
00407     int picstep = _resolution / PREVIEW_SIZE;
00408     // The color value to be drawn to the _picture:
00409     rgb col;
00410 
00411 
00412     if (!CbAutoUpdate->Checked) {
00413         FrameForm->StatusProgress->Position = 0;
00414         FrameForm->StatusProgress->Visible = true;
00415     }
00416 
00417     int x,y;
00418     for(y=0; y<PREVIEW_SIZE; ++y) { // line loop:
00419         for(x=0; x<PREVIEW_SIZE; ++x) { // pixel loop:
00420             pos = start;
00421             raylen = 0.0;
00422             col.r = col.g = col.b = 0;
00423             // Fast forward to the inside of the viewing volume, ...
00424             while (!_isInside(pos) && raylen <= l2) {
00425                 pos += viewy*5.0;
00426                 raylen += 5.0;
00427             }
00428             // ... one step back ...
00429             pos -= viewy*5.0; raylen -= 5.0;
00430             // ... and finally slowly into the volume:
00431             while (!(inside = _isInside(pos)) && raylen <= l2) {
00432                 pos += viewy*1.0;
00433                 raylen += 1.0;
00434             }
00435             // Fast forward to the first hit ...
00436             if (inside) {
00437                 val = _getValue(pos);
00438             } else {
00439                 val = 0;
00440             }
00441             while (inside && val<TbThres->Position &&
00442                    raylen <= l2) {
00443                 pos += viewy*3.0;
00444                 raylen += 3.0;
00445                 inside = _isInside(pos);
00446                 if (inside) {
00447                     val = _getValue(pos);
00448                 } else {
00449                     val = 0;
00450                 }
00451             }
00452             // ... one big step back ...
00453             pos -= viewy*3.0; raylen -= 3.0;
00454             if (inside = _isInside(pos)) {
00455                 val = _getValue(pos);
00456             } else {
00457                 val = 0;
00458             }
00459             // ... and slowly to the right position:
00460             while (inside && val<TbThres->Position &&
00461                    raylen <= l2) {
00462                 pos += viewy*1.0;
00463                 raylen += 1.0;
00464                 inside = _isInside(pos);
00465                 if (inside) {
00466                     val = _getValue(pos);
00467                 } else {
00468                     val = 0;
00469                 }
00470             }
00471             if (val >= TbThres->Position) {
00472                 vectorf normal = _getGradient(pos);
00473                 normal.normal();
00474                 //normal = normal*viewy;
00475                 vectorf specH = (viewy+lightDir)*0.5;
00476                 specH.normal();
00477                 float xxx = normal^specH;
00478                 xxx *= xxx;
00479                 xxx *= xxx;
00480                 //float len = normal.L;
00481                 /*
00482                 pixel->r = color[idx].r*(1.0-len);
00483                 pixel->g = color[idx].g*(1.0-len);
00484                 pixel->b = color[idx].b*(1.0-len);
00485                 */
00486                 /*
00487                 col.r = 255*(1.0-len);
00488                 col.g = 255*(1.0-len);
00489                 col.b = 255*(1.0-len);
00490                 */
00491                 col.r = col.g = col.b = 255*xxx;
00492             }
00493             _draw(col, x, y, picstep);
00494             start += viewx*step;
00495         }
00496         linestart += viewz*step;
00497         start = linestart;
00498 
00499         if (!CbAutoUpdate->Checked)
00500             FrameForm->StatusProgress->Position =
00501                 (int)((float)y/(float)PREVIEW_SIZE*100.0);
00502     }
00503     if (!CbAutoUpdate->Checked)
00504         FrameForm->StatusProgress->Visible = false;
00505 
00506     // Initializing the image calculation:
00507     _resetRenderer();
00508 }
00509 //---------------------------------------------------------------------------
00510 
00511 
00512 bool inline __fastcall TTwoLevelForm::_renderImage()
00513 {
00514 
00515 // This is used in the ray caster to get the value and area name from the
00516 // actual position pos.
00517 #define _GET_INSIDE_NAME_VAL    inside = _isInside(pos);                \
00518                                 if (inside) {                           \
00519                                     val = _getValue(pos);               \
00520                                     name = transe->getName(val);        \
00521                                     if (name != -1) myName = 1<<name;   \
00522                                     else            myName = 0;         \
00523                                 } else {                                \
00524                                     val = 0.0;                          \
00525                                     myName = 0;                         \
00526                                 }
00527 // How Long is a small step for:
00528 // First Hit:
00529 #define _SMALL_STEP_FH  0.1
00530 // MIP:
00531 #define _SMALL_STEP_MIP 0.5
00532 // NPR:
00533 #define _SMALL_STEP_NPR 0.5
00534 // NR:
00535 #define _SMALL_STEP_NR  0.5
00536 // Average:
00537 #define _SMALL_STEP_AVERAGE 0.5
00538 // Transparent:
00539 #define _SMALL_STEP_TRANSP 0.5
00540 
00541 
00542     //return false;
00543 
00544 
00545     // On any account turn on the progress bar:
00546     FrameForm->StatusProgress->Visible = true;
00547 
00548 
00549     // ================== Raycaster setup: ==============================
00551     // We assume the viewing plane lies in x-z-direction. This means:
00552     // * dragging in horizontal direction corresponds to a rotation around
00553     //   the z axis,
00554     // * dragging in vertical direction means a rotation around the x axis,
00555     // * the ray follows the positive y axis
00556 
00557     /************************************************************************
00558      * Moved to global and set up by _resertRenderer:
00559      *
00560      * // Viewing direction vectors:
00561      * vectord viewx(1,0,0), viewy(0,1,0), viewz(0,0,1);
00562      * // rotate them:
00563      * double rrotx = _rotx * M_PI / 180.0;
00564      * double rrotz = _rotz * M_PI / 180.0;
00565      * viewx.rotx(rrotx); viewx.rotz(rrotz); viewx.normal();
00566      * viewy.rotx(rrotx); viewy.rotz(rrotz); viewy.normal();
00567      * viewz.rotx(rrotx); viewz.rotz(rrotz); viewz.normal();
00568      * // Viewing volume center:
00569      * vectord center(sizeX/2, sizeY/2, sizeZ/2);
00570      * // Distance from volume middle to an edge:
00571      * //float l = _fm_sqrtl(sizeX*sizeX/4 + sizeY*sizeY/4 + sizeZ*sizeZ/4);
00572      * //float l = center.L;
00573      * double l = _dist, l2 = l*2.0;
00574      * // width of one step:
00575      * double step = 2*l/(float)_resolution;
00576      * // Start position of image:
00577      * vectord start = center + (viewx*(-l)) + (viewy*(-l)) + (viewz*(-l));
00578      * // Light position:
00579      * vectord lightPos = center + (viewy*(-l))
00580      *                    + (viewx*_lightX) + (viewz*_lightY);
00581      * // Light direction:
00582      * vectord lightDir = center - lightPos;
00583      * lightDir.normal();
00584      ***********************************************************************/
00585 
00586     // Actual position of ray:
00587     vectord pos;
00588     // Accumulator for the alpha value:
00589     double alpha = 0.0;
00590     // Insertion alpha value of the ray caster:
00591     double alphaRC = 0.0;
00592     // The local alpha value:
00593     double localAlpha;
00594     // The actual length of the ray:
00595     double raylen;
00596     // Actual data value:
00597     double val;
00598     // Data for the actual value;
00599     TData data;
00600     // The bit shifted area given by data.
00601     int name, myName;
00602     // Inside indicator:
00603     bool inside;
00604     // size of a pixel in the domain of _resolution:
00605     int picstep;
00606     // the two level accumulator color:
00607     rgb tlcol;
00608     // ray caster result color:
00609     rgb col;
00610 
00611 
00612     // ================== Image geometry setup: =========================
00613     bool finished = false;
00614     int i = 0;
00615 
00616 
00617     // Begin time mesurement:
00618     TDateTime stime = Time();
00619 
00620     // ================== Raycaster: ====================================
00621     while (i<_rpc && !finished) {
00623         picstep = _resolution / _actres;
00624         pos = _start + _viewx*(_step*_actposx*picstep)
00625                      + _viewz*(_step*_actposy*picstep);
00626         raylen = 0.0;
00627         val = 0.0;
00628         alpha = 0.0;
00629         tlcol.r = tlcol.g = tlcol.b = 0;
00630 
00631 
00633         // Fast forward to the inside of the viewing volume, ...
00634         while (!_isInside(pos) && raylen <= _l2) {
00635             pos += _viewy*5.0;
00636             raylen += 5.0;
00637         }
00638         // ... one step back ...
00639         pos -= _viewy*5.0; raylen -= 5.0;
00640         // ... and finally slowly into the volume:
00641         while (!(inside = _isInside(pos)) && raylen <= _l2) {
00642             pos += _viewy;
00643             raylen += 1.0;
00644         }
00645 
00646 
00650 
00651         // Calculate first value of this ray:
00652         _GET_INSIDE_NAME_VAL;
00653 
00654         while (inside && (raylen <= _l2) && alpha < 1.0) {
00655 
00656             // At this point a value should be calculated! So
00657             // either it is calculated befor the loop or at it's
00658             // end.
00659 
00660             // reset values:
00661             col.r = col.g = col.b = 0;
00662             localAlpha = 0.0;
00663             alphaRC = 0.0;
00664 
00665             if (!myName) {
00666                 // === None: ================================================
00667                 pos += _viewy;
00668                 raylen += 1.0;
00669                 _GET_INSIDE_NAME_VAL;
00670 
00671             } else if (myName & _firstHit) {
00672                 // === First Hit: ===========================================
00673 
00674                 // Set up First Hit:
00675                 alphaRC = _alphaFH;
00676 
00677                 // Fast forwart to the surface:
00678                 while ((myName & _firstHit) && (val < _thresFH) && inside) {
00679                     pos += _viewy;
00680                     raylen += 1.0;
00681                     _GET_INSIDE_NAME_VAL;
00682                 }
00683 
00684                 // The surface can only be detected if we are behind it. So
00685                 // Let's check this:
00686                 if ((myName & _firstHit) && (val >= _thresFH) && inside) {
00687                     // We ARE behind the surface
00688 
00689                     // One step back ...
00690                     pos -= _viewy*1.0;
00691                     raylen -= 1.0;
00692                     _GET_INSIDE_NAME_VAL;
00693 
00694                     // ... and small steps forward to the surface ...
00695                     while (((val < _thresFH)        // The last step back may
00696                             || !(myName & _firstHit)// have led out of the area
00697                             || !inside)             // or eaven out of the
00698                            && raylen < _l2) {       // volume, so go forth till
00699                                                     // we are inside again!
00700                         pos += _viewy*_SMALL_STEP_FH;
00701                         raylen += _SMALL_STEP_FH;
00702                         _GET_INSIDE_NAME_VAL;
00703                     }
00704 
00705                     // Found the surface, so let's draw the pixel:
00706                     if ((myName & _firstHit) && (val >= _thresFH) && inside) {
00707                         data = transe->getData(val);
00708                         vectord grad = _getGradient(pos);
00709                         grad.normal();
00710                         col = data.col;
00711                         localAlpha = data.alpha;
00712                         _calcColor(col, grad, _viewy, _lightDir);
00713                         col *= data.alpha;
00714                     }
00715 
00716                     // last of all fast forward to the end of the end of the
00717                     // area:
00718                     while ((myName & _firstHit) && inside) {
00719                         pos += _viewy;
00720                         raylen += 1.0;
00721                         _GET_INSIDE_NAME_VAL;
00722                     }
00723                 }
00724 
00725             } else if (myName & _MIP) {
00726                 // === MIP: =================================================
00727 
00728                 // Set up for MIP:
00729                 alphaRC = _alphaMIP;
00730                 double MIPval = 0.0;
00731 
00732                 // We are inside the area so let's take one step back ...
00733                 pos -= _viewy;
00734                 raylen -= 1.0;
00735                 _GET_INSIDE_NAME_VAL;
00736 
00737                 // ... slow forward to the border ...
00738                 while ((!(myName&_MIP) || !inside) && raylen<_l2) {
00739                     // While we are outside the area or outside the volume
00740                     // we step forth. But at most to the max. ray length!
00741                     pos += _viewy*_SMALL_STEP_MIP;
00742                     raylen += _SMALL_STEP_MIP;
00743                     _GET_INSIDE_NAME_VAL;
00744                 }
00745 
00746                 // ... and slowly through the area ...
00747                 while ((myName&_MIP) && inside) {
00748                     if (val>MIPval) {
00749                         // The highest value so far:
00750                         data = transe->getData(val);
00751                         //vectord grad = _getGradient(pos);
00752                         //grad.normal();
00753                         //col = data.col;
00754                         localAlpha = data.alpha;
00755                         //_calcColor(col, grad, _viewy, _lightDir);
00756                         col = _ambientCol*(_ambient*val/_MIPref);
00757                         MIPval = val;
00758                     }
00759                     pos += _viewy*_SMALL_STEP_MIP;
00760                     raylen += _SMALL_STEP_MIP;
00761                     _GET_INSIDE_NAME_VAL;
00762                 }
00763                 // ... till we are through.
00764 
00765             } else if (myName & _NPR) {
00766                 // === NPR: =================================================
00767 
00768                 // Set up for NPR:
00769                 alphaRC = _alphaNPR;
00770                 double gradMax = 0.0;
00771 
00772                 // We are inside the area so let's take one step back ...
00773                 pos -= _viewy;
00774                 raylen -= 1.0;
00775                 _GET_INSIDE_NAME_VAL;
00776 
00777                 // ... slow forward to the border ...
00778                 while ((!(myName&_NPR) || !inside) && raylen<_l2) {
00779                     // While we are outside the area or outside the volume
00780                     // we step forth. But at most to the max. ray length!
00781                     pos += _viewy*_SMALL_STEP_NPR;
00782                     raylen += _SMALL_STEP_NPR;
00783                     _GET_INSIDE_NAME_VAL;
00784                 }
00785 
00786                 // ... and slowly through the area ...
00787                 while ((myName&_NPR) && inside) {
00788                     // get gradient length for this position:
00789                     double gradlen = _getGradLength(pos);
00790                     if (gradlen>gradMax && gradlen>_NPRref) {
00791                         // As long as the ray is transparent:
00792                         data = transe->getData(val);
00793                         vectord grad = _getGradient(pos);
00794                         grad.normal();
00795                         rgb mycol;
00796                         mycol = data.col;
00797 
00798                         //_calcColor(mycol, grad, _viewy, _lightDir);
00799                         // Ambient:
00800                         double xxx = grad^_viewy;
00801                         if (xxx < 0.0) xxx *= -1.0;
00802                         //if (xxx < 0.0) xxx = 0.0;
00803                         xxx = 1-xxx;
00804                         switch (_NPRpower) {
00805                             case 10: xxx *= xxx;     // 1024
00806                             case  9: xxx *= xxx;     //  512
00807                             case  8: xxx *= xxx;     //  256
00808                             case  7: xxx *= xxx;     //  128
00809                             case  6: xxx *= xxx;     //   64
00810                             case  5: xxx *= xxx;     //   32
00811                             case  4: xxx *= xxx;     //   16
00812                             case  3: xxx *= xxx;     //    8
00813                             case  2: xxx *= xxx;     //    4
00814                             default: xxx *= xxx;     //    2
00815                         }
00816                         mycol.r *= (double)_ambientCol.r/255.0*_ambient*xxx;
00817                         mycol.g *= (double)_ambientCol.g/255.0*_ambient*xxx;
00818                         mycol.b *= (double)_ambientCol.b/255.0*_ambient*xxx;
00819                                     // Can do this without checking the result
00820                                     // for >255 cause all factors are less or
00821                                     // equal to one.
00822 
00823                         // Specular:
00824                         /*
00825                         vectord specH = (_viewy+_lightDir)*0.5;
00826                         specH.normal();
00827                         xxx = grad^specH;
00828                         xxx = 1-xxx;
00829                         if (xxx < 0.0) xxx *= -1.0;
00830                         xxx = acos(xxx);
00831                         if (xxx < 0.0)  xxx=0.0;
00832                         if (xxx>M_PI_2) xxx=M_PI_2;
00833                         xxx = 1.0-(xxx/M_PI_2);
00834                         switch (_power) {
00835                             case 10: xxx *= xxx;     // 1024
00836                             case  9: xxx *= xxx;     //  512
00837                             case  8: xxx *= xxx;     //  256
00838                             case  7: xxx *= xxx;     //  128
00839                             case  6: xxx *= xxx;     //   64
00840                             case  5: xxx *= xxx;     //   32
00841                             case  4: xxx *= xxx;     //   16
00842                             case  3: xxx *= xxx;     //    8
00843                             case  2: xxx *= xxx;     //    4
00844                             default: xxx *= xxx;     //    2
00845                         }
00846                         mycol += _lightCol*_light*xxx;
00847                         */
00848 
00849                         //localAlpha = data.alpha;
00850                         col = mycol*localAlpha;
00851                         col = mycol;
00852 
00853                         gradMax = gradlen;
00854                     }
00855                     pos += _viewy*_SMALL_STEP_NPR;
00856                     raylen += _SMALL_STEP_NPR;
00857                     _GET_INSIDE_NAME_VAL;
00858                 }
00859                 // ... till we are through.
00860 
00861             } else if (myName & _NR) {
00862                 // === NR: ==================================================
00863 
00864                 // Set up for NR:
00865                 alphaRC = _alphaNR;
00866                 double NRval = 0.0;
00867 
00868                 // We are inside the area so let's take one step back ...
00869                 pos -= _viewy;
00870                 raylen -= 1.0;
00871                 _GET_INSIDE_NAME_VAL;
00872 
00873                 // ... slow forward to the border ...
00874                 while ((!(myName&_NR) || !inside) && raylen<_l2) {
00875                     // While we are outside the area or outside the volume
00876                     // we step forth. But at most to the max. ray length!
00877                     pos += _viewy*_SMALL_STEP_NR;
00878                     raylen += _SMALL_STEP_NR;
00879                     _GET_INSIDE_NAME_VAL;
00880                 }
00881 
00882                 // ... and slowly through the area ...
00883                 while ((myName&_NR) && inside) {
00884                     if (val>NRval) {
00885                         // The highest value so far:
00886                         data = transe->getData(val);
00887                         vectord grad = _getGradient(pos);
00888                         grad.normal();
00889                         col = data.col;
00890                         localAlpha = data.alpha;
00891                         _calcColor(col, grad, _viewy, _lightDir);
00892                         //col = _ambientCol*(_ambient*val/4096.0);
00893                         NRval = val;
00894                     }
00895                     pos += _viewy*_SMALL_STEP_NR;
00896                     raylen += _SMALL_STEP_NR;
00897                     _GET_INSIDE_NAME_VAL;
00898                 }
00899                 // ... till we are through.
00900 
00901             } else if (myName & _Average) {
00902                 // === Average: =============================================
00903 
00904                 // Set up for average:
00905                 int averageCount = 0;
00906                 double averageVal = 0.0;
00907                 alphaRC = _alphaAverage;
00908                 localAlpha = 1.0;
00909 
00910                 // We are inside the area so let's take one step back ...
00911                 pos -= _viewy;
00912                 raylen -= 1.0;
00913                 _GET_INSIDE_NAME_VAL;
00914 
00915                 // ... slow forward to the border ...
00916                 while ((!(myName&_Average) || !inside) && raylen<_l2) {
00917                     // While we are outside the area or outside the volume
00918                     // we step forth. But at most to the max. ray length!
00919                     pos += _viewy*_SMALL_STEP_AVERAGE;
00920                     raylen += _SMALL_STEP_AVERAGE;
00921                     _GET_INSIDE_NAME_VAL;
00922                 }
00923 
00924                 // ... and slowly through the area ...
00925                 while ((myName&_Average) && inside) {
00926                     data = transe->getData(val);
00927                     averageVal += val*data.alpha;
00928                     ++averageCount;
00929                     pos += _viewy*_SMALL_STEP_AVERAGE;
00930                     raylen += _SMALL_STEP_AVERAGE;
00931                     _GET_INSIDE_NAME_VAL;
00932                 }
00933 
00934                 // ... till the end or the area.
00935 
00936                 averageVal /= (double)averageCount;
00937                 col.r = col.g = col.b = 255.0*averageVal/_Averageref;
00938 
00939             } else if (myName & _Transparent) {
00940                 // === Transparent: =========================================
00941 
00942                 // Set up for Transparent:
00943                 alphaRC = _alphaTransparent;
00944 
00945                 // We are inside the area so let's take one step back ...
00946                 pos -= _viewy;
00947                 raylen -= 1.0;
00948                 _GET_INSIDE_NAME_VAL;
00949 
00950                 // ... slow forward to the border ...
00951                 while ((!(myName&_Transparent) || !inside) && raylen<_l2) {
00952                     // While we are outside the area or outside the volume
00953                     // we step forth. But at most to the max. ray length!
00954                     pos += _viewy*_SMALL_STEP_TRANSP;
00955                     raylen += _SMALL_STEP_TRANSP;
00956                     _GET_INSIDE_NAME_VAL;
00957                 }
00958 
00959                 // ... and slowly through the area ...
00960                 while ((myName&_Transparent) && inside) {
00961                     if (localAlpha<1.0) {
00962                         // As long as the ray is transparent:
00963                         data = transe->getData(val);
00964                         vectord grad = _getGradient(pos);
00965                         grad.normal();
00966                         rgb mycol;
00967                         mycol = data.col;
00968                         _calcColor(mycol, grad, _viewy, _lightDir);
00969                         col += mycol*data.alpha*_SMALL_STEP_TRANSP;
00970                         localAlpha += data.alpha*_SMALL_STEP_TRANSP;
00971                     }
00972                     pos += _viewy*_SMALL_STEP_TRANSP;
00973                     raylen += _SMALL_STEP_TRANSP;
00974                     _GET_INSIDE_NAME_VAL;
00975                 }
00976                 // ... till we are through.
00977 
00978             } else {
00979                 // === None: ================================================
00980                 // This is for areas not assigned with a ray caster.
00981                 pos += _viewy*1.0;
00982                 raylen += 1.0;
00983                 _GET_INSIDE_NAME_VAL;
00984             }
00985 
00986             // Inserting the color value:
00987             if (alphaRC != 0.0) {
00988                 // Normize Alpha:
00989                 if (localAlpha > 1.0) localAlpha=1.0;
00990 
00991                 alpha += localAlpha*alphaRC;
00992                 tlcol += col*alphaRC;
00993             }
00994 
00995         }
00999 
01000 
01002         _draw(tlcol, _actposx, _actposy, picstep);
01003 
01004 
01006         // When a picture with dimention 8 should be drawn, the
01007         // resulting drawing order is like this (the number are the
01008         // resolution, at which the are set:
01009         // +-----------------+
01010         // | 2 8 4 8 2 8 4 8 |
01011         // | 8 8 8 8 8 8 8 8 |
01012         // | 4 8 4 8 4 8 4 8 |
01013         // | 8 8 8 8 8 8 8 8 |
01014         // | 2 8 4 8 2 8 4 8 |
01015         // | 8 8 8 8 8 8 8 8 |
01016         // | 4 8 4 8 4 8 4 8 |
01017         // | 8 8 8 8 8 8 8 8 |
01018         // +-----------------+
01019         if (_actres == 2) {     // the spezial resolution of 2:
01020             ++_actposx;
01021             if (_actposx == 2) {
01022                 _actposx = 0;
01023                 ++_actposy;
01024             }
01025             if (_actposy == 2) {
01026                 // move on to the next _actres:
01027                 _actres <<= 1;
01028                 _actposx = 1;   // from now on we allways start
01029                 _actposy = 0;   // on the second position in
01030                                 // the first row.
01031             }
01032         } else {                // all other resolutions:
01033             // on every line with even line-nr we increment x by 2:
01034             if (_actposy & 1)   _actposx++;
01035             else                _actposx += 2;
01036             if (_actposx >= _actres) {
01037                 // we are now at the end of a line:
01038                 ++_actposy;
01039                 // on every line with even line-nr we start at
01040                 // the second position:
01041                 if (_actposy & 1)   _actposx = 0;
01042                 else                _actposx = 1;
01043             }
01044             if (_actposy >= _actres) {
01045                 _actres <<= 1;  // move on to the next _actres.
01046                 _actposx = 1;   // as told above.
01047                 _actposy = 0;
01048                 if (picstep != 1) {
01049                     // For every even step size draw a while line at the right
01050                     // border. This line will be erased at every odd step size
01051                     // an therefor also at the end of drawing. It should be a
01052                     // simple progress display.
01053                     rgb myWhite;
01054                     myWhite.r = myWhite.g = myWhite.b = 255;
01055                     for(int j=0; j<_resolution; ++j)
01056                         _draw(myWhite, _resolution-11, j, 1);
01057                 }
01058             }
01059         }
01060         ++_progress;
01061         ++i;            // don't forget to count the number of rays
01062                         // calculated during this call of _renderImage
01063         finished = (_actres>_resolution);
01064         if (!(i%1000) || finished) {
01065             FrameForm->StatusProgress->Position =
01066                     (int)((float)_progress/(float)_pic_size*100.0);
01067             TDateTime dur = Time() - _startTime;
01068             TDateTime all = (double)dur / _progress * _pic_size;
01069             FrameForm->StatusMain->Caption = "ETA: " + (all - dur).TimeString();
01070             LTime->Caption = dur;
01071         }
01072     }
01073 
01074     // Stop time mesurement:
01075     unsigned short hh, min, sec, hsec;
01076     //TDateTime fdur = Time() - stime;
01077     (Time() - stime).DecodeTime(&hh, &min, &sec, &hsec);
01078     float t = (float)sec + (float)hsec/1000.0;
01079     if (t > _maxTime) {
01080         _rpc = _rpc*_maxTime/t;
01081     }
01082     Lrpc->Caption = AnsiString(_rpc) + " ("
01083                     + AnsiString::FormatFloat("0.000000", t) + ")";
01084 
01085     LProgress->Caption = AnsiString(_progress) + "/" + AnsiString(_pic_size);
01086 
01087     DrawingTimer->Enabled = !finished && !_stopIt;
01088     DrawingTimer->Interval = 150;
01089     FrameForm->StatusProgress->Visible = !finished && !_stopIt;
01090     if (finished || _stopIt) {
01091             FrameForm->StatusMain->Caption = "";
01092             SbStop->Enabled = false;
01093             SbStart->Enabled = true;
01094     }
01095     _stopIt = false;    // users wish should be met, so reset the 'signal'.
01096 
01097     PaintGL();
01098     return finished;
01099 }
01100 //---------------------------------------------------------------------------
01101 
01102 void inline __fastcall TTwoLevelForm::_render()
01103 {
01104     _renderPreview();
01105 }
01106 //---------------------------------------------------------------------------
01107 
01108 void inline __fastcall TTwoLevelForm::_draw(rgb &val, int x, int y, int step)
01109 {
01110     if (step == 1) {
01111         _picture[x + y*_resolution] = val;
01112     } else {
01113         for(int yy=y*step; yy<(y+1)*step; ++yy) {
01114             for(int xx=x*step; xx<(x+1)*step; ++xx) {
01115                 if ((xx + yy*_resolution) >= _pic_size)
01116                     cerr << "xx = " << xx << ", yy = " << yy << endl;
01117                 _picture[xx + yy*_resolution] = val;
01118             }
01119         }
01120     }
01121 }
01122 //---------------------------------------------------------------------------
01123 
01124 void inline __fastcall TTwoLevelForm::_resetRenderer()
01125 {
01126     if (_formCreate) return;
01127 
01128     DrawingTimer->Enabled = false;
01129     // Resolution things:
01130     _progress = 0;
01131     _actposx = 0;
01132     _actposy = 0;
01133     _actres = 2;
01134     _rpc = 10000;
01135 
01136     // Viewing plane:
01137     _viewx = vectord(1.0, 0.0, 0.0);
01138     _viewy = vectord(0.0, 1.0, 0.0);
01139     _viewz = vectord(0.0, 0.0, 1.0);
01140     double rrotx = _rotx * M_PI / 180.0;
01141     double rrotz = _rotz * M_PI / 180.0;
01142     _viewx.rotx(rrotx); _viewx.rotz(rrotz); _viewx.normal();
01143     _viewy.rotx(rrotx); _viewy.rotz(rrotz); _viewy.normal();
01144     _viewz.rotx(rrotx); _viewz.rotz(rrotz); _viewz.normal();
01145     // Viewing center:
01146     _center = vectord((double)sizeX/2.0, (double)sizeY/2.0, (double)sizeZ/2.0);
01147     // Ray lenght:
01148     _l2 = (double)_dist*2.0;
01149     // Step size:
01150     _step = _l2/(float)_resolution;
01151     // Picture start position:
01152     _start = _center + (_viewx*(double)(-_dist))
01153              + (_viewy*(double)(-_dist))
01154              + (_viewz*(double)(-_dist));
01155     // Light position:
01156     _lightPos = _center + (_viewy*(double)(-_dist))
01157                 + (_viewx*_lightX) + (_viewz*_lightY);
01158     // Light direction:
01159     _lightDir = _center - _lightPos;
01160     _lightDir.normal();
01161 
01162     //LLength->Caption = AnsiString(_l2);
01163 
01164     SbStop->Enabled = true;
01165     SbStart->Enabled = false;
01166 
01167     // Fire it up:
01168     DrawingTimer->Enabled = true;
01169     DrawingTimer->Interval = 500;
01170     _startTime = Time();
01171 }
01172 //---------------------------------------------------------------------------
01173 
01174 bool inline __fastcall TTwoLevelForm::_isInside(vectorf & v)
01175 {
01176     return (v.X >= 1.0) && (v.X < (float)(sizeX-1)) &&
01177            (v.Y >= 1.0) && (v.Y < (float)(sizeY-1)) &&
01178            (v.Z >= 1.0) && (v.Z < (float)(sizeZ-1));
01179 }
01180 //---------------------------------------------------------------------------
01181 
01182 bool inline __fastcall TTwoLevelForm::_isInside(vectord & v)
01183 {
01184     return (v.X >= 1.0) && (v.X < (double)(sizeX-1)) &&
01185            (v.Y >= 1.0) && (v.Y < (double)(sizeY-1)) &&
01186            (v.Z >= 1.0) && (v.Z < (double)(sizeZ-1));
01187 }
01188 //---------------------------------------------------------------------------
01189 
01190 void TTwoLevelForm::_setupTLAlpha(TSpeedButton* sb, TEdit* e,
01191                                   TTabSheet* ts, double f)
01192 {
01193     if (sb->Down) {
01194         PTwoLevelAlpha->Top = PageControl1->Top + ts->Top + e->Top + e->Height;
01195         PTwoLevelAlpha->Left = PageControl1->Left + ts->Left + e->Left;
01196         _TwoLevelAlphaEdit = e; // Change the edit box to be
01197                                 // manipulated by the track bar BEFOR
01198                                 // changing the track bars position!
01199         TbTwoLevelAlpha->Position = (int)(f * 1000.0);
01200         PTwoLevelAlpha->Visible = true;
01201     } else {
01202         PTwoLevelAlpha->Visible = false;
01203     }
01204 }
01205 //---------------------------------------------------------------------------
01206 
01207 void TTwoLevelForm::_setupRef(TSpeedButton* sb, TEdit* e,
01208                               TTabSheet* ts, double f)
01209 {
01210     if (sb->Down) {
01211         PRef->Top = PageControl1->Top + ts->Top + e->Top + e->Height;
01212         PRef->Left = PageControl1->Left + ts->Left + e->Left;
01213         _RefEdit = e;   // Change the edit box to be
01214                         // manipulated by the track bar BEFOR
01215                         // changing the track bars position!
01216         TbRef->Position = f;
01217         PRef->Visible = true;
01218     } else {
01219         PRef->Visible = false;
01220     }
01221 }
01222 //---------------------------------------------------------------------------
01223 
01224 void TTwoLevelForm::_setupListBox(TListBox* lb, int& rc)
01225 {
01226     lb->Items->Assign(transe->areaNames);
01227     int idx = _getFirstBitIndex(rc);
01228     while (idx != -1) {
01229         if (idx < lb->Items->Count)
01230             lb->Selected[idx] = true;
01231         else
01232             rc &= ~(1<<idx);    // unset the bit if the idx
01233                                 // is out of range.
01234         idx = _getNextBitIndex(rc);
01235     }
01236 }
01237 //---------------------------------------------------------------------------
01238 
01239 void __fastcall TTwoLevelForm::_unsetBitInAllRCs(int idx)
01240 {
01241     _firstHit &= ~(1<<idx);
01242     _MIP &= ~(1<<idx);
01243     _NPR &= ~(1<<idx);
01244     _Average &= ~(1<<idx);
01245     _Transparent &= ~(1<<idx);
01246 }
01247 //---------------------------------------------------------------------------
01248 
01249 void __fastcall TTwoLevelForm::PaintGL()
01250 {
01251     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01252     PrepareGLWindow();
01253     glColor3f(0.6f,0.6f,0.6f);
01254     glLineWidth(3.0f);
01255     glBegin(GL_LINE_STRIP);
01256     glVertex3f(-50,-50,0);
01257     glVertex3f(50,-50,0);
01258     glVertex3f(50,50,0);
01259     glVertex3f(-50,50,0);
01260     glVertex3f(-50,-50,0);
01261     glEnd();
01262 
01263     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01264     glDrawPixels(_resolution, _resolution, GL_RGB,
01265                  GL_UNSIGNED_BYTE, _picture);
01266                     // we use unsigned byte (char) to meet speed issues.
01267                     // 16 bit data (__int16) slows down drawing to much.
01268 
01269     glFlush();
01270     SwapBuffers(hdc);
01271 }
01272 
01273 void __fastcall TTwoLevelForm::PrepareGLWindow()
01274 {
01275     wglMakeCurrent(hdc, hrc);
01276 
01277     GLfloat nRange = 50.0;
01278     w = ClientWidth-200;
01279     h = ClientHeight;
01280 
01281     if(h == 0) h = 1;
01282     if(w == 0) w = 1;
01283 
01284     glViewport(200, 0, w, h);
01285     glLoadIdentity();
01286 
01287     if (w <= h) {
01288         glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
01289         glPixelZoom((float)w/(float)_resolution, (float)w/(float)_resolution);
01290     } else {
01291         glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
01292         glPixelZoom((float)h/(float)_resolution, (float)h/(float)_resolution);
01293     }
01294 
01295     glRasterPos2d(-50,-50);
01296 }
01297 //---------------------------------------------------------------------------
01298 
01299 void __fastcall TTwoLevelForm::SetPixelFormatDescriptor()
01300 {
01301     PIXELFORMATDESCRIPTOR pfd = {
01302         sizeof(PIXELFORMATDESCRIPTOR),
01303         1,
01304         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
01305         PFD_TYPE_RGBA,
01306         24,
01307         0,0,0,0,0,0,
01308         0,0,
01309         0,0,0,0,0,
01310         32,
01311         0,
01312         0,
01313         PFD_MAIN_PLANE,
01314         0,
01315         0,0,
01316     };
01317     PixelFormat = ChoosePixelFormat(hdc, &pfd);
01318     SetPixelFormat(hdc, PixelFormat, &pfd);
01319 }
01320 //---------------------------------------------------------------------
01321 
01322 void __fastcall TTwoLevelForm::FormCreate(TObject *Sender)
01323 {
01324     _picture = 0;
01325     _rowsize = sizeX;
01326     _pagesize = sizeX*sizeY;
01327     _dist = MAX(MAX(sizeX, sizeY), sizeZ) >> 1;
01328     _resize();
01329 
01331     // Setting up UI:
01332     LRotation->Caption = AnsiString(_rotx) + ", " + AnsiString(_rotz);
01333     LDist->Caption = AnsiString(_dist);
01334 
01335     TbThres->Position = _thres;
01336     PThres->Top = PageControl1->Top + TsPreview->Top
01337                   + EThres->Top + EThres->Height;
01338     PThres->Left = PageControl1->Left + TsPreview->Left
01339                    + EThres->Left + 4;
01340 
01341     EmaxTime->Text = AnsiString::FormatFloat("0.000", _maxTime);
01342     PmaxTime->Top = PageControl1->Top + TsCommon->Top
01343                     + EmaxTime->Top + EmaxTime->Height;
01344     PmaxTime->Left = PageControl1->Left + TsCommon->Left
01345                      + EmaxTime->Left;
01346 
01347     // Ambient:
01348     EAmbient->Text = AnsiString::FormatFloat("0.000", _ambient);
01349     PAmbient->Top = PageControl1->Top + TsCommon->Top
01350                     + EAmbient->Top + EAmbient->Height;
01351     PAmbient->Left = PageControl1->Left + TsCommon->Left
01352                      + EAmbient->Left;
01353     _ambientCol = TColor2RGB(SAmbient->Brush->Color);
01354 
01355     // Light:
01356     ELight->Text = AnsiString::FormatFloat("0.000", _light);
01357     PLight->Top = PageControl1->Top + TsCommon->Top
01358                   + ELight->Top + ELight->Height;
01359     PLight->Left = PageControl1->Left + TsCommon->Left
01360                    + ELight->Left;
01361     _lightCol = TColor2RGB(SLight->Brush->Color);
01362     LLightPos->Caption = AnsiString(_lightX) + " x " + AnsiString(_lightY);
01363 
01364     // Power:
01365     _power = TbPower->Position;
01366     LPower->Caption = AnsiString(1<<_power);
01367     _sinus = CbSinus->Checked;
01368 
01369     // First Hit:
01370     EFHAlpha->Text = AnsiString::FormatFloat("0.000", _alphaFH);
01371     EFHThres->Text = AnsiString(_thresFH);
01372     PFHThres->Top = PageControl1->Top + TsFirstHit->Top
01373                     + EFHThres->Top + EFHThres->Height;
01374     PFHThres->Left = PageControl1->Left + TsFirstHit->Left
01375                      + EFHThres->Left;
01376     LbFirstHit->Items->Assign(transe->areaNames);
01377 
01378     // MIP:
01379     EMIPAlpha->Text = AnsiString::FormatFloat("0.000", _alphaMIP);
01380     LbMIP->Items->Assign(transe->areaNames);
01381     EMIPRef->Text = AnsiString(_MIPref);
01382 
01383     // NPR:
01384     ENPRAlpha->Text = AnsiString::FormatFloat("0.000", _alphaNPR);
01385     LbNPR->Items->Assign(transe->areaNames);
01386     TbNPRPower->Position = _NPRpower;
01387     LNPRPower->Caption = AnsiString(1<<_power);
01388     ENPRRef->Text = AnsiString(_NPRref);
01389 
01390     // Average:
01391     EAverageAlpha->Text = AnsiString::FormatFloat("0.000", _alphaAverage);
01392     LbAverage->Items->Assign(transe->areaNames);
01393 
01394     // Transparent:
01395     ETransparentAlpha->Text = AnsiString::FormatFloat("0.000",
01396                                                       _alphaTransparent);
01397     LbTransparent->Items->Assign(transe->areaNames);
01398     EAverageRef->Text = AnsiString(_Averageref);
01399 
01400 
01401     PageControl1->ActivePage = TsCommon;
01403 
01404     hdc = GetDC(Handle);
01405     SetPixelFormatDescriptor();
01406     hrc = wglCreateContext(hdc);
01407     if(hrc == NULL) ShowMessage("Could not create DC!");
01408     wglMakeCurrent(hdc, hrc);
01409 
01410     w = ClientWidth;
01411     h = ClientHeight;
01412 
01413     glEnable(GL_DEPTH_TEST);
01414     glEnable(GL_CULL_FACE);
01415 
01416     glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
01417     glOrtho (-50.0,50.0,-50.0,50.0,-50.0,50.0);
01418 
01419     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01420     glFlush();
01421     SwapBuffers(hdc);
01422     FormResize(Sender);
01423 
01424     _formCreate = false;
01425 }
01426 //---------------------------------------------------------------------
01427 
01428 void __fastcall TTwoLevelForm::FormClose(TObject *Sender, TCloseAction &Action)
01429 {
01430     Action=caFree;
01431 
01432     FrameForm->StatusMain->Caption = "";
01433     FrameForm->StatusProgress->Visible = false;
01434 
01435     FrameForm->TwoLevel->Checked = false;
01436     memusage = memusage - 3*_resolution*_resolution;
01437     if (_picture) {
01438         delete [] _picture;
01439         _picture = 0;
01440     }
01441     FrameForm->memupdate();
01442     wglDeleteContext(hrc);
01443     ReleaseDC(Handle,hdc);
01444 }
01445 //---------------------------------------------------------------------
01446 
01447 void __fastcall TTwoLevelForm::FormResize(TObject *Sender)
01448 {
01449     CbWindowSizeClick(this);
01450     PrepareGLWindow();
01451     PaintGL();
01452 }
01453 //---------------------------------------------------------------------------
01454 
01455 void __fastcall TTwoLevelForm::FormPaint(TObject *Sender)
01456 {
01457     PaintGL();
01458 }
01459 //---------------------------------------------------------------------------
01460 
01461 void __fastcall TTwoLevelForm::FormActivate(TObject *Sender)
01462 {
01463     TsFirstHitShow(this);
01464     TsMIPShow(this);
01465     TsNPRShow(this);
01466     TsAverageShow(this);
01467     TsTransparentShow(this);
01468     PaintGL();
01469 }
01470 //---------------------------------------------------------------------------
01471 
01472 void __fastcall TTwoLevelForm::FormClick(TObject *Sender)
01473 {
01474     //_render();
01475     //PaintGL();
01476 }
01477 //---------------------------------------------------------------------------
01478 
01479 void __fastcall TTwoLevelForm::FormMouseDown(TObject *Sender,
01480       TMouseButton Button, TShiftState Shift, int X, int Y)
01481 {
01482     _startX = X;
01483     _startY = Y;
01484     _traging = true;
01485     _rightButton = (Button == mbRight);
01486 }
01487 //---------------------------------------------------------------------------
01488 
01489 void __fastcall TTwoLevelForm::FormMouseMove(TObject *Sender,
01490       TShiftState Shift, int X, int Y)
01491 {
01492     if (_traging) {
01493         if (_rightButton) {
01494             _dist -= (Y-_startY)>>1;
01495         } else {
01496             if (Shift.Contains(ssCtrl)) {
01497                 // Light Moving:
01498                 _lightX  += (double)(X-_startX)/2.0;
01499                 _lightY  -= (double)(Y-_startY)/2.0;
01500             } else {
01501                 _rotz -= (X-_startX)>>1;
01502                 _rotx -= (Y-_startY)>>1;
01503                 if (_rotx < 0)   _rotx += 360;
01504                 if (_rotx > 360) _rotx -= 360;
01505                 if (_rotz < 0)   _rotz += 360;
01506                 if (_rotz > 360) _rotz -= 360;
01507             }
01508         }
01509         _startX = X;
01510         _startY = Y;
01511         LRotation->Caption = AnsiString(_rotx) + ", " + AnsiString(_rotz);
01512         LLightPos->Caption = AnsiString(_lightX) + " x " + AnsiString(_lightY);
01513         LDist->Caption = AnsiString(_dist);
01514         if (CbAutoUpdate->Checked) {
01515             _render();
01516             PaintGL();
01517         }
01518     }
01519 }
01520 //---------------------------------------------------------------------------
01521 
01522 void __fastcall TTwoLevelForm::FormMouseUp(TObject *Sender,
01523       TMouseButton Button, TShiftState Shift, int X, int Y)
01524 {
01525     _traging = false;
01526     if (!CbAutoUpdate->Checked) {
01527         _render();
01528         PaintGL();
01529     }
01530 }
01531 //---------------------------------------------------------------------------
01532 
01533 void __fastcall TTwoLevelForm::CbWindowSizeClick(TObject *Sender)
01534 {
01535     if (CbWindowSize->Checked) {
01536         _oldres = _resolution;
01537         _resolution = TwoLevelForm->ClientHeight;
01538         TbResolution->Enabled = false;
01539         LResolution->Enabled = false;
01540         _resize();
01541         _render();
01542     } else {
01543         TbResolution->Enabled = true;
01544         LResolution->Enabled = true;
01545         TbResolutionChange(this);
01546     }
01547 }
01548 //---------------------------------------------------------------------------
01549 
01550 void __fastcall TTwoLevelForm::TbResolutionChange(TObject *Sender)
01551 {
01552     _oldres = _resolution;
01553     switch(TbResolution->Position) {
01554         case 1:  _resolution =  128; break;
01555         case 2:  _resolution =  256; break;
01556         case 3:  _resolution =  512; break;
01557         case 4:  _resolution = 1024; break;
01558         case 5:  _resolution = 2048; break;
01559         case 6:  _resolution = 4096; break;
01560         default: _resolution =  128; break;
01561     }
01562     CbResizeClick(this);
01563     if (_oldres != _resolution) {
01564         _resize();
01565         _render();
01566         PaintGL();
01567     }
01568 }
01569 //---------------------------------------------------------------------------
01570 
01571 void __fastcall TTwoLevelForm::CbResizeClick(TObject *Sender)
01572 {
01573     if (CbResize->Checked) {
01574         if (CbWindowSize->Checked) {
01575             CbWindowSize->Checked = false;
01576             TbResolution->Enabled = true;
01577             LResolution->Enabled = true;
01578             TbResolutionChange(this);
01579         }
01580         if (_resolution > 256) {
01581             ClientHeight = _resolution;
01582             ClientWidth = _resolution + 200;
01583         }
01584     }
01585 }
01586 //---------------------------------------------------------------------------
01587 
01588 void __fastcall TTwoLevelForm::TbThresChange(TObject *Sender)
01589 {
01590     EThres->Text = AnsiString(TbThres->Position);
01591     if (CbAutoUpdate->Checked) {
01592         _render();
01593         PaintGL();
01594     }
01595 }
01596 //---------------------------------------------------------------------------
01597 
01598 void __fastcall TTwoLevelForm::DrawingTimerTimer(TObject *Sender)
01599 {
01600     DrawingTimer->Enabled = false;
01601     _renderImage();
01602 }
01603 //---------------------------------------------------------------------------
01604 
01605 void __fastcall TTwoLevelForm::Button1Click(TObject *Sender)
01606 {
01607     PaintGL();
01608 }
01609 //---------------------------------------------------------------------------
01610 
01611 void __fastcall TTwoLevelForm::TbmaxTimeChange(TObject *Sender)
01612 {
01613     EmaxTime->Text =
01614         AnsiString::FormatFloat("0.000", (float)TbmaxTime->Position/1000.0);
01615 }
01616 //---------------------------------------------------------------------------
01617 
01618 void __fastcall TTwoLevelForm::EmaxTimeChange(TObject *Sender)
01619 {
01620     _maxTime = EmaxTime->Text.ToDouble();
01621 }
01622 //---------------------------------------------------------------------------
01623 
01624 void __fastcall TTwoLevelForm::TbmaxTimeExit(TObject *Sender)
01625 {
01626     PmaxTime->Visible = !PmaxTime->Visible;
01627     SbmaxTime->Down = PmaxTime->Visible;
01628 }
01629 //---------------------------------------------------------------------------
01630 
01631 void __fastcall TTwoLevelForm::SbmaxTimeClick(TObject *Sender)
01632 {
01633     TbmaxTime->Position = _maxTime * 1000.0;
01634     PmaxTime->Visible = !PmaxTime->Visible;
01635     SbmaxTime->Down = PmaxTime->Visible;
01636 }
01637 //---------------------------------------------------------------------------
01638 
01639 void __fastcall TTwoLevelForm::SbThresClick(TObject *Sender)
01640 {
01641     TbThres->Position = _thres;
01642     PThres->Visible = !PThres->Visible;
01643     SbThres->Down = PThres->Visible;
01644 }
01645 //---------------------------------------------------------------------------
01646 
01647 void __fastcall TTwoLevelForm::EThresChange(TObject *Sender)
01648 {
01649     _thres = EThres->Text.ToInt();
01650     if (CbAutoUpdate->Checked) {
01651         _render();
01652         PaintGL();
01653     }
01654 }
01655 //---------------------------------------------------------------------------
01656 
01657 void __fastcall TTwoLevelForm::TbThresExit(TObject *Sender)
01658 {
01659     PThres->Visible = !PThres->Visible;
01660     SbThres->Down = PThres->Visible;
01661 }
01662 //---------------------------------------------------------------------------
01663 
01664 void __fastcall TTwoLevelForm::PageControl1Changing(TObject *Sender,
01665       bool &AllowChange)
01666 {
01667     PThres->Visible = false;
01668     SbThres->Down = false;
01669     PmaxTime->Visible = false;
01670     SbmaxTime->Down = false;
01671     PTwoLevelAlpha->Visible = false;
01672     SbFHAlpha->Down = false;
01673     PFHThres->Visible = false;
01674     SbFHThres->Down = false;
01675     SbMIPAlpha->Down = false;
01676     SbNPRAlpha->Down = false;
01677     SbAverageAlpha->Down = false;
01678     SbTransparentAlpha->Down = false;
01679     SbAmbient->Down = false;
01680     PAmbient->Visible = false;
01681     SbLight->Down = false;
01682     PLight->Visible = false;
01683     PRef->Visible = false;
01684     SbMIPRef->Down = false;
01685     SbNPRRef->Down = false;
01686 }
01687 //---------------------------------------------------------------------------
01688 
01689 void __fastcall TTwoLevelForm::SbFHAlphaClick(TObject *Sender)
01690 {
01691     _setupTLAlpha(SbFHAlpha, EFHAlpha, TsFirstHit, _alphaFH);
01692 }
01693 //---------------------------------------------------------------------------
01694 
01695 void __fastcall TTwoLevelForm::TbTwoLevelAlphaChange(TObject *Sender)
01696 {
01697     _TwoLevelAlphaEdit->Text =
01698         AnsiString::FormatFloat(
01699             "0.000000", (double)TbTwoLevelAlpha->Position/1000.0);
01700 }
01701 //---------------------------------------------------------------------------
01702 
01703 void __fastcall TTwoLevelForm::EFHAlphaChange(TObject *Sender)
01704 {
01705     _alphaFH = AnsiString(EFHAlpha->Text).ToDouble();
01706     _resetRenderer();
01707 }
01708 //---------------------------------------------------------------------------
01709 
01710 void __fastcall TTwoLevelForm::EFHThresChange(TObject *Sender)
01711 {
01712     _thresFH = AnsiString(EFHThres->Text).ToInt();
01713     _resetRenderer();
01714 }
01715 //---------------------------------------------------------------------------
01716 
01717 void __fastcall TTwoLevelForm::SbFHThresClick(TObject *Sender)
01718 {
01719     TbFHThres->Position = _thresFH;
01720     PFHThres->Visible = !PFHThres->Visible;
01721     SbFHThres->Down = PFHThres->Visible;
01722 }
01723 //---------------------------------------------------------------------------
01724 
01725 void __fastcall TTwoLevelForm::LbFirstHitClick(TObject *Sender)
01726 {
01727     if (LbFirstHit->ItemIndex != -1) {
01728         _unsetBitInAllRCs(LbFirstHit->ItemIndex);
01729         _firstHit = 1 << LbFirstHit->ItemIndex;
01730     }
01731     _resetRenderer();
01732 }
01733 //---------------------------------------------------------------------------
01734 
01735 void __fastcall TTwoLevelForm::LbFirstHitDblClick(TObject *Sender)
01736 {
01737     LbFirstHit->ItemIndex = -1;
01738     _firstHit = 0;
01739     _resetRenderer();
01740 }
01741 //---------------------------------------------------------------------------
01742 
01743 void __fastcall TTwoLevelForm::TbFHThresChange(TObject *Sender)
01744 {
01745     EFHThres->Text = AnsiString(TbFHThres->Position);
01746 }
01747 //---------------------------------------------------------------------------
01748 
01749 void __fastcall TTwoLevelForm::TsFirstHitShow(TObject *Sender)
01750 {
01751     LbFirstHit->Items->Assign(transe->areaNames);
01752     LbFirstHit->ItemIndex = _getFirstBitIndex(_firstHit);
01753 }
01754 //---------------------------------------------------------------------------
01755 
01756 void __fastcall TTwoLevelForm::SbMIPAlphaClick(TObject *Sender)
01757 {
01758     _setupTLAlpha(SbMIPAlpha, EMIPAlpha, TsMIP, _alphaMIP);
01759 }
01760 //---------------------------------------------------------------------------
01761 
01762 void __fastcall TTwoLevelForm::EMIPAlphaChange(TObject *Sender)
01763 {
01764     _alphaMIP = AnsiString(EMIPAlpha->Text).ToDouble();
01765     _resetRenderer();
01766 }
01767 //---------------------------------------------------------------------------
01768 
01769 void __fastcall TTwoLevelForm::LbMIPClick(TObject *Sender)
01770 {
01771     _MIP = 0;
01772     for(int i=0; i<LbMIP->Items->Count; ++i) {
01773         if (LbMIP->Selected[i]) {
01774             _unsetBitInAllRCs(i);
01775             _MIP |= 1<<i;
01776         }
01777     }
01778     _resetRenderer();
01779 }
01780 //---------------------------------------------------------------------------
01781 
01782 void __fastcall TTwoLevelForm::LbMIPDblClick(TObject *Sender)
01783 {
01784     LbMIP->Selected[LbMIP->ItemIndex] = false;
01785     LbMIPClick(this);
01786     _resetRenderer();
01787 }
01788 //---------------------------------------------------------------------------
01789 
01790 void __fastcall TTwoLevelForm::TsMIPShow(TObject *Sender)
01791 {
01792     _setupListBox(LbMIP, _MIP);
01793 }
01794 //---------------------------------------------------------------------------
01795 
01796 void __fastcall TTwoLevelForm::ENPRAlphaChange(TObject *Sender)
01797 {
01798     _alphaNPR = AnsiString(ENPRAlpha->Text).ToDouble();
01799     _resetRenderer();
01800 }
01801 //---------------------------------------------------------------------------
01802 
01803 void __fastcall TTwoLevelForm::SbNPRAlphaClick(TObject *Sender)
01804 {
01805     _setupTLAlpha(SbNPRAlpha, ENPRAlpha, TsNPR, _alphaNPR);
01806 }
01807 //---------------------------------------------------------------------------
01808 
01809 void __fastcall TTwoLevelForm::LbNPRClick(TObject *Sender)
01810 {
01811     _NPR = 0;
01812     for(int i=0; i<LbNPR->Items->Count; ++i) {
01813         if (LbNPR->Selected[i]) {
01814             _unsetBitInAllRCs(i);
01815             _NPR |= 1<<i;
01816         }
01817     }
01818     _resetRenderer();
01819 }
01820 //---------------------------------------------------------------------------
01821 
01822 void __fastcall TTwoLevelForm::LbNPRDblClick(TObject *Sender)
01823 {
01824     LbNPR->Selected[LbNPR->ItemIndex] = false;
01825     LbNPRClick(this);
01826     _resetRenderer();
01827 }
01828 //---------------------------------------------------------------------------
01829 
01830 void __fastcall TTwoLevelForm::TsNPRShow(TObject *Sender)
01831 {
01832     _setupListBox(LbNPR, _NPR);
01833 }
01834 //---------------------------------------------------------------------------
01835 
01836 void __fastcall TTwoLevelForm::EAverageAlphaChange(TObject *Sender)
01837 {
01838     _alphaAverage = AnsiString(EAverageAlpha->Text).ToDouble();
01839     _resetRenderer();
01840 }
01841 //---------------------------------------------------------------------------
01842 
01843 void __fastcall TTwoLevelForm::SbAverageAlphaClick(TObject *Sender)
01844 {
01845     _setupTLAlpha(SbAverageAlpha, EAverageAlpha, TsAverage, _alphaAverage);
01846 }
01847 //---------------------------------------------------------------------------
01848 
01849 void __fastcall TTwoLevelForm::LbAverageClick(TObject *Sender)
01850 {
01851     _Average = 0;
01852     for(int i=0; i<LbAverage->Items->Count; ++i) {
01853         if (LbAverage->Selected[i]) {
01854             _unsetBitInAllRCs(i);
01855             _Average |= 1<<i;
01856         }
01857     }
01858     _resetRenderer();
01859 }
01860 //---------------------------------------------------------------------------
01861 
01862 void __fastcall TTwoLevelForm::LbAverageDblClick(TObject *Sender)
01863 {
01864     LbAverage->Selected[LbAverage->ItemIndex] = false;
01865     LbAverageClick(this);
01866     _resetRenderer();
01867 }
01868 //---------------------------------------------------------------------------
01869 
01870 void __fastcall TTwoLevelForm::TsAverageShow(TObject *Sender)
01871 {
01872     _setupListBox(LbAverage, _Average);
01873 }
01874 //---------------------------------------------------------------------------
01875 
01876 void __fastcall TTwoLevelForm::ETransparentAlphaChange(TObject *Sender)
01877 {
01878     _alphaTransparent = AnsiString(ETransparentAlpha->Text).ToDouble();
01879     _resetRenderer();
01880 }
01881 //---------------------------------------------------------------------------
01882 
01883 void __fastcall TTwoLevelForm::SbTransparentAlphaClick(TObject *Sender)
01884 {
01885     _setupTLAlpha(SbTransparentAlpha, ETransparentAlpha,
01886                   TsTransparent, _alphaTransparent);
01887 }
01888 //---------------------------------------------------------------------------
01889 
01890 void __fastcall TTwoLevelForm::LbTransparentClick(TObject *Sender)
01891 {
01892     _Transparent = 0;
01893     for(int i=0; i<LbTransparent->Items->Count; ++i) {
01894         if (LbTransparent->Selected[i]) {
01895             _unsetBitInAllRCs(i);
01896             _Transparent |= 1<<i;
01897         }
01898     }
01899     _resetRenderer();
01900 }
01901 //---------------------------------------------------------------------------
01902 
01903 void __fastcall TTwoLevelForm::LbTransparentDblClick(TObject *Sender)
01904 {
01905     LbTransparent->Selected[LbTransparent->ItemIndex] = false;
01906     LbTransparentClick(this);
01907     _resetRenderer();
01908 }
01909 //---------------------------------------------------------------------------
01910 
01911 void __fastcall TTwoLevelForm::TsTransparentShow(TObject *Sender)
01912 {
01913     _setupListBox(LbTransparent, _Transparent);
01914 }
01915 //---------------------------------------------------------------------------
01916 
01917 void __fastcall TTwoLevelForm::EAmbientChange(TObject *Sender)
01918 {
01919     _ambient = EAmbient->Text.ToDouble();
01920     TbAmbient->Position = (int)(_ambient * 1000.0);
01921     _resetRenderer();
01922 }
01923 //---------------------------------------------------------------------------
01924 
01925 void __fastcall TTwoLevelForm::SAmbientMouseUp(TObject *Sender,
01926       TMouseButton Button, TShiftState Shift, int X, int Y)
01927 {
01928     ColorDialog1->Color = SAmbient->Brush->Color;
01929     if (ColorDialog1->Execute()) {
01930         SAmbient->Brush->Color = ColorDialog1->Color;
01931         _ambientCol = TColor2RGB(ColorDialog1->Color);
01932         _resetRenderer();
01933     }
01934 }
01935 //---------------------------------------------------------------------------
01936 
01937 void __fastcall TTwoLevelForm::SbAmbientClick(TObject *Sender)
01938 {
01939     TbAmbient->Position = _ambient*1000;
01940     PAmbient->Visible = !PAmbient->Visible;
01941     SbAmbient->Down = PAmbient->Visible;
01942 }
01943 //---------------------------------------------------------------------------
01944 
01945 void __fastcall TTwoLevelForm::TbAmbientChange(TObject *Sender)
01946 {
01947     EAmbient->Text =
01948         AnsiString::FormatFloat(
01949             "0.000", (double)TbAmbient->Position/1000.0);
01950 }
01951 //---------------------------------------------------------------------------
01952 
01953 void __fastcall TTwoLevelForm::ELightChange(TObject *Sender)
01954 {
01955     _light = ELight->Text.ToDouble();
01956     TbLight->Position = (int)(_light * 1000.0);
01957     _resetRenderer();
01958 }
01959 //---------------------------------------------------------------------------
01960 
01961 void __fastcall TTwoLevelForm::SLightMouseUp(TObject *Sender,
01962       TMouseButton Button, TShiftState Shift, int X, int Y)
01963 {
01964     ColorDialog1->Color = SLight->Brush->Color;
01965     if (ColorDialog1->Execute()) {
01966         SLight->Brush->Color = ColorDialog1->Color;
01967         _lightCol = TColor2RGB(ColorDialog1->Color);
01968         _resetRenderer();
01969     }
01970 }
01971 //---------------------------------------------------------------------------
01972 
01973 void __fastcall TTwoLevelForm::SbLightClick(TObject *Sender)
01974 {
01975     TbLight->Position = _light * 1000;
01976     PLight->Visible = !PLight->Visible;
01977     SbLight->Down = PLight->Visible;
01978 }
01979 //---------------------------------------------------------------------------
01980 
01981 void __fastcall TTwoLevelForm::TbLightChange(TObject *Sender)
01982 {
01983     ELight->Text =
01984         AnsiString::FormatFloat(
01985             "0.000", (double)TbLight->Position/1000.0);
01986 }
01987 //---------------------------------------------------------------------------
01988 
01989 void __fastcall TTwoLevelForm::TbPowerChange(TObject *Sender)
01990 {
01991     _power = TbPower->Position;
01992     LPower->Caption = AnsiString(1<<_power);
01993     _resetRenderer();
01994 }
01995 //---------------------------------------------------------------------------
01996 
01997 void __fastcall TTwoLevelForm::TbNPRPowerChange(TObject *Sender)
01998 {
01999     _NPRpower = TbNPRPower->Position;
02000     LNPRPower->Caption = AnsiString(1<<_power);
02001     _resetRenderer();
02002 }
02003 //---------------------------------------------------------------------------
02004 
02005 void __fastcall TTwoLevelForm::CbSinusClick(TObject *Sender)
02006 {
02007     _sinus = CbSinus->Checked;
02008     _resetRenderer();
02009 }
02010 //---------------------------------------------------------------------------
02011 
02012 void __fastcall TTwoLevelForm::TbRefChange(TObject *Sender)
02013 {
02014     _RefEdit->Text = AnsiString(TbRef->Position);
02015 }
02016 //---------------------------------------------------------------------------
02017 
02018 void __fastcall TTwoLevelForm::SbMIPRefClick(TObject *Sender)
02019 {
02020     _setupRef(SbMIPRef, EMIPRef, TsMIP, _MIPref);
02021 }
02022 //---------------------------------------------------------------------------
02023 
02024 void __fastcall TTwoLevelForm::EMIPRefChange(TObject *Sender)
02025 {
02026     _MIPref = AnsiString(EMIPRef->Text).ToDouble();
02027     _resetRenderer();
02028 }
02029 //---------------------------------------------------------------------------
02030 
02031 void __fastcall TTwoLevelForm::SbNPRRefClick(TObject *Sender)
02032 {
02033     _setupRef(SbNPRRef, ENPRRef, TsNPR, _NPRref);
02034 }
02035 //---------------------------------------------------------------------------
02036 
02037 void __fastcall TTwoLevelForm::ENPRRefChange(TObject *Sender)
02038 {
02039     _NPRref = AnsiString(ENPRRef->Text).ToDouble();
02040     _resetRenderer();
02041 }
02042 //---------------------------------------------------------------------------
02043 
02044 void __fastcall TTwoLevelForm::SbAverageRefClick(TObject *Sender)
02045 {
02046     _setupRef(SbAverageRef, EAverageRef, TsAverage, _Averageref);
02047 }
02048 //---------------------------------------------------------------------------
02049 
02050 void __fastcall TTwoLevelForm::EAverageRefChange(TObject *Sender)
02051 {
02052     _Averageref = AnsiString(EAverageRef->Text).ToDouble();
02053     _resetRenderer();
02054 }
02055 //---------------------------------------------------------------------------
02056 
02057 void __fastcall TTwoLevelForm::SbStopClick(TObject *Sender)
02058 {
02059     _stopIt = true;    
02060 }
02061 //---------------------------------------------------------------------------
02062 
02063 void __fastcall TTwoLevelForm::SbSaveJpgClick(TObject *Sender)
02064 {
02065     SbSaveJpg->Enabled = false;
02066     if (SaveDialogImage->Execute()) {
02067         Graphics::TBitmap *b = new Graphics::TBitmap();
02068         b->PixelFormat = pf24bit;
02069         b->Width = _resolution;
02070         b->Height = _resolution;
02071         for(int y=0; y<b->Height; ++y) {
02072             for(int x=0; x<b->Width; ++x) {
02073                 b->Canvas->Pixels[x][y] =
02074                     RGB2TColor(_picture[x + (_resolution-1-y)*_resolution]);
02075             }
02076         }
02077         TJPEGImage *jp = new TJPEGImage();
02078         jp->Assign(b);
02079         jp->SaveToFile(SaveDialogImage->FileName);
02080     }
02081     SbSaveJpg->Enabled = false;
02082 }
02083 //---------------------------------------------------------------------------
02084 
02085 void __fastcall TTwoLevelForm::SbStartClick(TObject *Sender)
02086 {
02087     _resetRenderer();
02088 }
02089 //---------------------------------------------------------------------------
02090 

Generated on Thu Jan 23 06:17:39 2003 for Vol by doxygen1.2.18