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