00001
00002
00003 #include <vcl.h>
00004 #pragma hdrstop
00005
00006 #include "MDIFirstHit.h"
00007 #include "MDIEdit.h"
00008 #include "MDIFrame.h"
00009 #include <math.h>
00010 #include <fastmath.h>
00011
00012
00013 #pragma package(smart_init)
00014 #pragma resource "*.dfm"
00015
00016 #define MIN(x,y) ((x<y) ? (x) : (y))
00017 #define MAX(x,y) ((x>y) ? (x) : (y))
00018 rgb *firstview;
00019 TFirstHitForm *FirstHitForm;
00020
00021 const float pi=3.141592;
00022 const float pi2=2*pi;
00023 const float pih=pi/2;
00024 const float pirad=pi/180;
00025
00026 bool mdown;
00027
00028
00029 __fastcall TFirstHitForm::TFirstHitForm(TComponent* Owner)
00030 : TForm(Owner)
00031 {
00032 }
00033
00034 void __fastcall TFirstHitForm::SetPixelFormatDescriptor()
00035 {
00036 PIXELFORMATDESCRIPTOR pfd = {
00037 sizeof(PIXELFORMATDESCRIPTOR),
00038 1,
00039 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
00040 PFD_TYPE_RGBA,
00041 24,
00042 0,0,0,0,0,0,
00043 0,0,
00044 0,0,0,0,0,
00045 32,
00046 0,
00047 0,
00048 PFD_MAIN_PLANE,
00049 0,
00050 0,0,0
00051 };
00052
00053 PixelFormat = ChoosePixelFormat(hdc, &pfd);
00054 SetPixelFormat(hdc, PixelFormat, &pfd);
00055 }
00056
00057
00058 void __fastcall TFirstHitForm::FormClose(TObject *Sender, TCloseAction &Action)
00059 {
00060 delete [] firstview;
00061 Action=caFree;
00062 FrameForm->FirstHit->Checked = false;
00063 memusage = memusage - 3*1024*1024;
00064 FrameForm->memupdate();
00065 wglDeleteContext(hrc);
00066 ReleaseDC(Handle,hdc);
00067 }
00068
00069 void __fastcall TFirstHitForm::FormCreate(TObject *Sender)
00070 {
00071 int i,a;
00072
00073 firstview = new rgb[1024*1024];
00074 memusage = memusage + 3*1024*1024;
00075 FrameForm->memupdate();
00076
00077 mrotx=0; mroty=0;xres=256;yres=256;thresh = 400;
00078 hdc = GetDC(Handle);
00079 SetPixelFormatDescriptor();
00080 hrc = wglCreateContext(hdc);
00081 if(hrc == NULL) ShowMessage("Could not create DC!");
00082 wglMakeCurrent(hdc, hrc);
00083
00084 w = ClientWidth;
00085 h = ClientHeight;
00086
00087 glEnable(GL_DEPTH_TEST);
00088 glEnable(GL_CULL_FACE);
00089
00090 glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
00091 glOrtho (-50.0,50.0,-50.0,50.0,-50.0,50.0);
00092
00093 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00094 glFlush();
00095 SwapBuffers(hdc);
00096 FormResize(Sender);
00097 RayCast();
00098 }
00099
00100 void __fastcall TFirstHitForm::FormResize(TObject *Sender)
00101 {
00102 tPanel->Height = ClientHeight-34;
00103 TrackBar->Height = ClientHeight-36;
00104 PrepareGLWindow();
00105 if (autores->Checked) {RayCast();}
00106 PaintGL();
00107 }
00108
00109 void __fastcall TFirstHitForm::FormPaint(TObject *Sender)
00110 {
00111 PaintGL();
00112 }
00113
00114 void __fastcall TFirstHitForm::PaintGL()
00115 {
00116 float i;
00117
00118 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00119 PrepareGLWindow();
00120 glColor3f(0.6f,0.6f,0.6f);
00121 glLineWidth(3.0f);
00122 glBegin(GL_LINE_STRIP);
00123 glVertex3f(-50,-50,0);
00124 glVertex3f(50,-50,0);
00125 glVertex3f(50,50,0);
00126 glVertex3f(-50,50,0);
00127 glVertex3f(-50,-50,0);
00128 glEnd();
00129
00130 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00131 glDrawPixels(xres, yres, GL_RGB, GL_UNSIGNED_BYTE,firstview);
00132
00133
00134
00135 glFlush();
00136 SwapBuffers(hdc);
00137 }
00138
00139 void __fastcall TFirstHitForm::PrepareGLWindow()
00140 {
00141 wglMakeCurrent(hdc, hrc);
00142
00143 GLfloat nRange = 50.0;
00144 w = ClientWidth-200;
00145 h = ClientHeight;
00146
00147 if(h == 0) h = 1;
00148 if(w == 0) w = 1;
00149
00150 glViewport(200, 0, w, h);
00151 glLoadIdentity();
00152
00153 if (w <= h)
00154 { glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
00155 glPixelZoom((float)w/(float)xres, (float)w/(float)yres);}
00156 else
00157 { glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
00158 glPixelZoom((float)h/(float)xres, (float)h/(float)yres);}
00159
00160 glRasterPos2d(-50,-50);
00161 }
00162
00163
00164
00165 void __fastcall TFirstHitForm::FormActivate(TObject *Sender)
00166 {
00167 PaintGL();
00168 }
00169
00170
00171 void __fastcall TFirstHitForm::RayCast()
00172 {
00173 int a,i,j,k,maxres;
00174 __int16 value;
00175 int aktpos, rowsize,pagesize, px, py, pz;
00176 int h,ita, ite, detval, detincval;
00177 float t,ta,te,tx,ty,tz,xrcos,yrcos,zrcos,xrsin,yrsin,zrsin,xrot,yrot,zrot;
00178 float valgx,valgy,valgz,value1,value2,value3, value4, value11, value22,pfx,pfy,pfz,sx,sy,sz,s1x,s1y;
00179 float temp;
00180 bool detset;
00181 double valsh, ac, ac2;
00182 float lx, ly, lz;
00183 unsigned char col;
00184
00185 detval=DetTrackBar->Position-1;
00186 vertex pppos;
00187 vertex dlookup[1024];
00188 if (autores->Checked)
00189 { if (w>h) {xres=h;yres=h;} else {xres=w;yres=w;} }
00190 else
00191 {
00192 xres = StrToInt(textx->Caption);
00193 yres = StrToInt(texty->Caption);
00194 }
00195 xrot = (float)StrToFloat(txrot->Text)*pirad;
00196
00197 zrot = (float)StrToFloat(tzrot->Text)*pirad;
00198
00199 xrcos = _fm_cos(xrot);
00200
00201 zrcos = _fm_cos(zrot);
00202 xrsin = _fm_sin(xrot);
00203
00204 zrsin = _fm_sin(zrot);
00205
00206 FrameForm->StatusProgress->Position = 0;
00207 FrameForm->StatusProgress->Visible = true;
00208 maxres = MAX(MAX(sizeX,sizeY),sizeZ);
00209
00210
00211 lx =0; ly=1; lz=0;
00212
00213 temp = ly;
00214 ly = temp*xrcos - lz * xrsin;
00215 lz = temp*xrsin + lz * xrcos;
00216
00217 temp = lx;
00218 lx = temp*zrcos - ly * zrsin;
00219 ly = temp*zrsin + ly * zrcos;
00220
00221
00222 dx.x = (float)maxres/(float)xres;
00223 dx.y = 0;
00224 dx.z = 0;
00225
00226 temp = dx.y;
00227
00228 dx.x = dx.x;
00229 dx.y = temp * xrcos - dx.z*xrsin;
00230 dx.z = temp * xrsin + dx.z*xrcos;
00231
00232 temp = dx.x;
00233
00234 dx.x = temp * zrcos - dx.y * zrsin;
00235 dx.y = temp * zrsin + dx.y * zrcos;
00236 dx.z = dx.z;
00237
00238 dy.x = 0;
00239 dy.y = 0;
00240 dy.z = (float)maxres/(float)yres;
00241
00242 temp = dy.y;
00243
00244 dy.x = dy.x;
00245 dy.y = temp * xrcos - dy.z*xrsin;
00246 dy.z = temp * xrsin + dy.z*xrcos;
00247
00248 temp = dy.x;
00249
00250 dy.x = temp * zrcos - dy.y * zrsin;
00251 dy.y = temp * zrsin + dy.y * zrcos;
00252 dy.z = dy.z;
00253
00254
00255 dz.x = 0;
00256 dz.y = 1;
00257 dz.z = 0;
00258
00259 temp = dz.y;
00260
00261 dz.x = dz.x;
00262 dz.y = temp * xrcos - dz.z*xrsin;
00263 dz.z = temp * xrsin + dz.z*xrcos;
00264
00265 temp = dz.x;
00266
00267 dz.x = temp * zrcos - dz.y * zrsin;
00268 dz.y = temp * zrsin + dz.y * zrcos;
00269 dz.z = dz.z;
00270
00271 o.x = -(maxres/2);
00272 o.y = -(sizeY/2);
00273 o.z = -(maxres/2);
00274
00275 temp = o.y;
00276
00277 o.x = o.x;
00278 o.y = temp * xrcos - o.z*xrsin;
00279 o.z = temp * xrsin + o.z*xrcos;
00280
00281 temp = o.x;
00282
00283 o.x = temp * zrcos - o.y * zrsin;
00284 o.y = temp * zrsin + o.y * zrcos;
00285 o.z = o.z;
00286
00287 o.x = o.x + sizeX/2;
00288 o.y = o.y + sizeY/2;
00289 o.z = o.z + sizeZ/2;
00290
00291 pagesize = sizeX*sizeY;
00292 rowsize = sizeX;
00293
00294 for (i=0; i<1024; i++)
00295 {
00296 dlookup[i].x = (i-512) * dz.x;
00297 dlookup[i].y = (i-512) * dz.y;
00298 dlookup[i].z = (i-512) * dz.z;
00299 }
00300
00301 k = 0;
00302 for (a=0; a<yres; a++)
00303 {
00304 pppos.x = o.x + a * dy.x;
00305 pppos.y = o.y + a * dy.y;
00306 pppos.z = o.z + a * dy.z;
00307
00308 if (arepaint->Checked == false) {FrameForm->StatusProgress->Position = (int)(100 * ((float)a / (float)yres));}
00309 for (i=0; i<xres; i++)
00310 {
00311 ppos.x = pppos.x + i * dx.x;
00312 ppos.y = pppos.y + i * dx.y;
00313 ppos.z = pppos.z + i * dx.z;
00314
00315 ta = 9999;
00316 te = 9999;
00317
00318 if (dz.x!=0)
00319 {
00320 t = -ppos.x/dz.x;
00321 ty = ppos.y + t*dz.y;
00322 tz = ppos.z + t*dz.z;
00323 if (ty>=0 && tz>=2 && ty<sizeY-1 && tz<sizeZ-3) { if (ta==9999) ta=t; else te=t; }
00324
00325 t = (sizeX-1-ppos.x)/dz.x;
00326 ty = ppos.y + t*dz.y;
00327 tz = ppos.z + t*dz.z;
00328 if (ty>=0 && tz>=2 && ty<sizeY-1 && tz<sizeZ-3) { if (ta==9999) ta=t; else te=t; }
00329 }
00330
00331 if (dz.y!=0)
00332 {
00333 t = -ppos.y/dz.y;
00334 tx = ppos.x + t*dz.x;
00335 tz = ppos.z + t*dz.z;
00336 if (tx>=0 && tz>=2 && tx<sizeX-1 && tz<sizeZ-3) { if (ta==9999) ta=t; else te=t; }
00337
00338 t = (sizeY-1-ppos.y)/dz.y;
00339 tx = ppos.x + t*dz.x;
00340 tz = ppos.z + t*dz.z;
00341 if (tx>=0 && tz>=2 && tx<sizeX-1 && tz<sizeZ-3) { if (ta==9999) ta=t; else te=t; }
00342 }
00343
00344 if (dz.z!=0)
00345 {
00346 t = (2-ppos.z)/dz.z;
00347 tx = ppos.x + t*dz.x;
00348 ty = ppos.y + t*dz.y;
00349 if (tx>=0 && ty>=0 && tx<sizeX-1 && ty<sizeY-1) { if (ta==9999) ta=t; else te=t; }
00350
00351 t = (sizeZ-3-ppos.z)/dz.z;
00352 tx = ppos.x + t*dz.x;
00353 ty = ppos.y + t*dz.y;
00354 if (tx>=0 && ty>=0 && tx<sizeX-1 && ty<sizeY-1) { if (ta==9999) ta=t; else te=t; }
00355 }
00356
00357 if (ta>te) {t=ta; ta=te; te=t;}
00358
00359 detset=0;
00360
00361 if (te==9999)
00362 {
00363 firstview[k].r=firstview[k].b=firstview[k].g = 0;
00364 }
00365 else
00366 {
00367 value = 0; ita = (int)ta+512; ite = (int)te+512-detval;
00368 for (j=ita; j<ite && value<thresh; j++)
00369 { if (detset==0) j += detval;
00370
00371
00372
00373
00374
00375 label1: pfx = (ppos.x) + dlookup[j].x;
00376 pfy = (ppos.y) + dlookup[j].y;
00377 pfz = (ppos.z) + dlookup[j].z;
00378
00379 px = (int)pfx;
00380 py = (int)pfy;
00381 pz = (int)pfz;
00382 aktpos = pagesize*pz + rowsize*py + px;
00383 if (trilinear->Checked)
00384 {
00385 sx = pfx-px;
00386 sy = pfy-py;
00387 sz = pfz-pz;
00388 s1x = 1-sx;
00389 s1y = 1-sy;
00390 value1 = (float)data[aktpos]*s1x + (float)data[aktpos+1]*sx;
00391 value2 = (float)data[aktpos+rowsize]*s1x + (float)data[aktpos+rowsize+1]*sx;
00392 value3 = (float)data[aktpos+pagesize+rowsize]*s1x + (float)data[aktpos+pagesize+rowsize+1]*sx;
00393 value4 = (float)data[aktpos+pagesize]*s1x + (float)data[aktpos+pagesize+1]*sx;
00394 value11 = value1*(s1y) + value2*(sy);
00395 value22 = value4*(s1y) + value3*(sy);
00396 value = (int)(value11*(1-sz) + value22*(sz));
00397 }
00398 else
00399 {
00400 value = data[pagesize*pz + rowsize*py + px];
00401 }
00402
00403 if (value>= thresh)
00404
00405 { if (adapt->Checked) { if (detset==0 && detval>0) {detset=1;j -= detval; goto label1;}}
00406 if (trilinear2->Checked)
00407 {
00408 sx = pfx-px;
00409 sy = pfy-py;
00410 sz = pfz-pz;
00411 s1x = 1-sx;
00412
00413 value1 = (float)gradient[aktpos].y*s1x + (float)gradient[aktpos+1].y*sx;
00414 value2 = (float)gradient[aktpos+rowsize].y*s1x + (float)gradient[aktpos+rowsize+1].y*sx;
00415 value3 = (float)gradient[aktpos+pagesize+rowsize].y*s1x + (float)gradient[aktpos+pagesize+rowsize+1].y*sx;
00416 value4 = (float)gradient[aktpos+pagesize].y*s1x + (float)gradient[aktpos+pagesize+1].y*sx;
00417 value11 = value1*(1-sy) + value2*(sy);
00418 value22 = value4*(1-sy) + value3*(sy);
00419 valgy=((value11*(1-sz) + value22*(sz)));
00420
00421 value1 = (float)gradient[aktpos].x*s1x + (float)gradient[aktpos+1].x*sx;
00422 value2 = (float)gradient[aktpos+rowsize].x*s1x + (float)gradient[aktpos+rowsize+1].x*sx;
00423 value3 = (float)gradient[aktpos+pagesize+rowsize].x*s1x + (float)gradient[aktpos+pagesize+rowsize+1].x*sx;
00424 value4 = (float)gradient[aktpos+pagesize].x*s1x + (float)gradient[aktpos+pagesize+1].x*sx;
00425 value11 = value1*(1-sy) + value2*(sy);
00426 value22 = value4*(1-sy) + value3*(sy);
00427 valgx=((value11*(1-sz) + value22*(sz)));
00428
00429 value1 = (float)gradient[aktpos].z*s1x + (float)gradient[aktpos+1].z*sx;
00430 value2 = (float)gradient[aktpos+rowsize].z*s1x + (float)gradient[aktpos+rowsize+1].z*sx;
00431 value3 = (float)gradient[aktpos+pagesize+rowsize].z*s1x + (float)gradient[aktpos+pagesize+rowsize+1].z*sx;
00432 value4 = (float)gradient[aktpos+pagesize].z*s1x + (float)gradient[aktpos+pagesize+1].z*sx;
00433 value11 = value1*(1-sy) + value2*(sy);
00434 value22 = value4*(1-sy) + value3*(sy);
00435 valgz=((value11*(1-sz) + value22*(sz)));
00436
00437 valsh = fabs(valgx*lx+valgy*ly+valgz*lz);
00438 if (valsh<0) {valsh=0.0;}
00439
00440 ac = (_fm_acosl(valsh));
00441 if (ac<0) {ac=0;}
00442 if (ac>pih) {ac=pih;}
00443 ac = 1-(ac/pih);
00444
00445
00446
00447
00448
00449 if (highlights->Checked) {
00450 valsh = valsh*valsh;
00451 valsh = valsh*valsh;
00452 valsh = valsh*valsh;
00453 valsh = valsh*valsh;
00454 valsh = valsh*valsh;
00455 valsh = valsh*valsh;
00456 ac2 = valsh + ac;
00457 h = (int)255*ac2;
00458 if (h>255) {col=255;} else {col = h;}
00459 }
00460 else {col = (int)255*ac;}
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 firstview[k].r=firstview[k].b=firstview[k].g = (col);
00488
00489 }
00490 else
00491 {
00492 valsh = fabs(gradient[pagesize*pz + rowsize*py + px].x*lx+gradient[pagesize*pz + rowsize*py + px].y*ly+gradient[pagesize*pz + rowsize*py + px].z*lz);
00493
00494
00495 ac=_fm_acos(valsh);
00496 if (ac<0) {ac=0;}
00497 if (ac>pih) {ac=pih;}
00498 ac = 1-(ac/pih);
00499
00500 if (highlights->Checked) {
00501 valsh = valsh*valsh;
00502 valsh = valsh*valsh;
00503 valsh = valsh*valsh;
00504 valsh = valsh*valsh;
00505 valsh = valsh*valsh;
00506 valsh = valsh*valsh;
00507 ac2 = valsh + ac;
00508 h = (int)255*ac2;
00509 if (h>255) {col=255;} else {col = h;}
00510 }
00511 else {col = (int)255*ac;}
00512
00513
00514
00515
00516
00517
00518
00519
00520 firstview[k].r=firstview[k].b=firstview[k].g = col;
00521
00522
00523 }
00524 }
00525 else {firstview[k].r=firstview[k].b=firstview[k].g=20;
00526 firstview[k].b=30;}
00527 }
00528 }
00529
00530 k++;
00531 }
00532 }
00533 FrameForm->StatusProgress->Visible = false;
00534 }
00535
00536 void __fastcall TFirstHitForm::TrackBarChange(TObject *Sender)
00537 {
00538 threshhold->Caption = IntToStr(TrackBar->Position);
00539 thresh = TrackBar->Position;
00540 if (arepaint->Checked) {RayCast(); PaintGL(); }
00541 }
00542
00543
00544 void __fastcall TFirstHitForm::FormMouseDown(TObject *Sender,
00545 TMouseButton Button, TShiftState Shift, int X, int Y)
00546 {
00547 mdown=true;
00548 ox = X;
00549 oy = Y;
00550 }
00551
00552
00553
00554
00555 void __fastcall TFirstHitForm::FormMouseUp(TObject *Sender,
00556 TMouseButton Button, TShiftState Shift, int X, int Y)
00557 {
00558 mdown=false;
00559 RayCast();
00560 PaintGL();
00561 }
00562
00563
00564 void __fastcall TFirstHitForm::FormMouseMove(TObject *Sender,
00565 TShiftState Shift, int X, int Y)
00566 {
00567 if (mdown)
00568 {
00569 mrotx -= (Y-oy);
00570 mroty -= (X-ox);
00571 if (mrotx<0) mrotx += 360;
00572 if (mrotx>360) mrotx -= 360;
00573 if (mroty<0) mroty += 360;
00574 if (mroty>360) mroty -= 360;
00575
00576 if (arepaint->Checked) {RayCast(); PaintGL(); }
00577 txrot->Text = IntToStr(mrotx);
00578 tzrot->Text = IntToStr(mroty);
00579 ox = X;
00580 oy = Y;
00581 }
00582 }
00583
00584
00585 void __fastcall TFirstHitForm::autoresClick(TObject *Sender)
00586 {
00587 if (autores->Checked==true)
00588 {
00589 ResTrackBar->Enabled=false;
00590 textx->Enabled=false;
00591 Label2->Enabled=false;
00592 texty->Enabled=false;
00593 }
00594 else
00595 {
00596 ResTrackBar->Enabled=true;
00597 textx->Enabled=true;
00598 Label2->Enabled=true;
00599 texty->Enabled=true;
00600 }
00601 if (arepaint->Checked) {RayCast();PaintGL();}
00602
00603 }
00604
00605
00606 void __fastcall TFirstHitForm::adaptClick(TObject *Sender)
00607 {
00608 if (arepaint->Checked) {RayCast();PaintGL();}
00609 }
00610
00611
00612 void __fastcall TFirstHitForm::ResTrackBarChange(TObject *Sender)
00613 {
00614 switch (ResTrackBar->Position)
00615 {
00616 case 1: textx->Caption = "32"; texty->Caption = "32"; break;
00617 case 2: textx->Caption = "64"; texty->Caption = "64"; break;
00618 case 3: textx->Caption = "128"; texty->Caption = "128"; break;
00619 case 4: textx->Caption = "256"; texty->Caption = "256"; break;
00620 case 5: textx->Caption = "512"; texty->Caption = "512"; break;
00621 case 6: textx->Caption = "1024"; texty->Caption = "1024";
00622 }
00623 if (arepaint->Checked) {RayCast();PaintGL();}
00624 }
00625
00626
00627 void __fastcall TFirstHitForm::DetTrackBarChange(TObject *Sender)
00628 {
00629 detail->Caption = IntToStr(DetTrackBar->Position);
00630 if (arepaint->Checked) {RayCast();PaintGL();}
00631 }
00632
00633
00634 void __fastcall TFirstHitForm::trilinearClick(TObject *Sender)
00635 {
00636 if (arepaint->Checked) {RayCast();PaintGL();}
00637
00638 }
00639
00640
00641 void __fastcall TFirstHitForm::trilinear2Click(TObject *Sender)
00642 {
00643 if (arepaint->Checked) {RayCast();PaintGL();}
00644
00645 }
00646
00647
00648
00649
00650