Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

ProgRad.cc

Go to the documentation of this file.
00001 /*
00002     File:           ProgRad.cc
00003 
00004     Function:       See header file
00005 
00006     Author:         Andrew Willmott
00007 
00008     Notes:          
00009 */
00010 
00011 #include "ProgRad.h"
00012 #include "gcl/Draw.h"
00013 
00027 Void ProgRad::MakeFormFactorFromVector(RadElem &fromPatch, 
00028     PatchList &patches, ColourList &result)
00029 // Find the vector of patch factors from patch j. 
00030 // The factors are weighted by the reflectance of the patch they are to.
00031 {
00032     Int         i, k;
00033     GCLReal     visibility;
00034     GCLReal     factor;
00035     RadElem     *curPatch;
00036         
00037     result.SetSize(patches.NumItems());
00038         
00039 #ifdef RAD_VIS
00040     if (gRadControl->showRays)
00041         display->Clear().Draw(GetScene());
00042 #endif
00043     
00044     for (i = 0; i < patches.NumItems(); i++)        
00045     {   
00046         GCLReal rho;
00047                 
00048         curPatch = patches[i];
00049         
00050         rho = len(curPatch->Reflectance());
00051         
00052         if (rho < 0.0001)
00053         {
00054             result[i] = vl_0;
00055             continue;
00056         }
00057 
00058         factor = fromPatch.EstFormFactor(curPatch);
00059 #ifdef RAD_SPEEDY
00060         if (rho * factor < 1e-5)
00061         {
00062             result[i] = vl_0;
00063             continue;
00064         }
00065 #endif
00066 
00067         visibility = fromPatch.Visibility(curPatch);
00068         
00069         if (visibility > 0.0001)
00070         {
00071             result[i] = curPatch->Reflectance();
00072             result[i] *= factor * visibility;
00073         }
00074         else
00075             result[i] = vl_0;
00076     }
00077     
00078 #ifdef RAD_VIS
00079     if (gRadControl->showRays)
00080         display->Show();
00081 #endif
00082 }
00083 
00084 Bool ProgRad::Render()
00085 //  Returns true if no interruptions.
00086 {
00087     Int         numPatches = patches.NumItems();
00088     Int         i, j;
00089     
00090     Colour      deltaRad;
00091     Colour      radToShoot;
00092     GCLReal     power, envArea;
00093     Colour      envPower, envRefl;
00094     Bool        finished = 0;   
00095     
00096     RadMethod::Render();
00097 
00098     iterations = 0;
00099     error = 1.0;
00100     origShoot = 0;
00101         
00102     B.SetSize(numPatches);
00103     S.SetSize(numPatches);
00104 
00105     envRad = vl_1;
00106             
00107     if (Stage(1)) return(0);
00108     
00109     for (i = 0; i < patches.NumItems(); i++)
00110         S[i] = patches[i]->Emittance();
00111     
00112     B = S;
00113                 
00114     //  Setup for the ambient term
00115 
00116     envRefl.MakeZero();
00117     envArea = 0;
00118     
00119     for (i = 0; i < numPatches; i++)
00120     {
00121         envRefl += patches[i]->area * patches[i]->Reflectance();
00122         envArea += patches[i]->area;    
00123     }
00124     
00125     envRefl /= Colour(vl_1) / (Colour(vl_1) - envRefl / envArea);
00126     // R = 1 / (1 - avgReflectance)
00127     
00128     //  Now, run the algorithm...
00129 
00130     while (!finished)
00131     {   
00132         if (Stage(2)) return(0);
00133 
00134         iterations++;
00135 
00136         maxPower = 0;
00137         maxPowerIndex = 0;
00138         envPower.MakeZero();
00139         
00140         for (i = 0; i < numPatches; i++)                        
00141         {
00142             power = dot(S[i] * patches[i]->area, kRadRGBToLum);
00143                 
00144             if (maxPower < power)
00145             {
00146                 maxPower = power;
00147                 maxPowerIndex = i;
00148             }
00149         }
00150         
00151         if (Idle()) 
00152             return(0);
00153 
00154         if (Stage(3)) return(0);
00155             
00156         radToShoot = S[maxPowerIndex];
00157         radToShoot *= gRadControl->alpha;
00158         S[maxPowerIndex] -= radToShoot;
00159                 
00160         if (Stage(4)) return(0);
00161                 
00162 #ifdef RAD_VIS
00163         if (gRadControl->drawMatrix)
00164             MakeFormFactorFromVector(*patches[maxPowerIndex], patches,
00165                     FFRows[maxPowerIndex]);
00166         else            
00167 #else
00168         MakeFormFactorFromVector(*patches[maxPowerIndex], patches, FFRow);
00169 #endif
00170 
00171         if (Stage(5)) return(0);
00172         
00173         error = 0;
00174         envPower.MakeZero();
00175                 
00176         for (i = 0; i < numPatches; i++)
00177         {
00178 #ifdef RAD_VIS
00179             if (gRadControl->drawMatrix)
00180                 deltaRad = FFRows[maxPowerIndex][i] * radToShoot;
00181             else
00182 #endif
00183             deltaRad = FFRow[i] * radToShoot;
00184             B[i] += deltaRad;
00185             S[i] += deltaRad;
00186             error += sqrlen(deltaRad);
00187 
00188             envPower += S[i] * patches[i]->area;
00189         }
00190         
00191         if (gRadControl->ambient)
00192             envRad = envRefl * envPower / envArea;
00193         else
00194             envRad.MakeZero();
00195 
00196         error = sqrt(error);
00197 
00198         if (iterations == 1)
00199             origShoot = maxPower;
00200         else if (maxPower < gRadControl->error * origShoot)
00201             finished = 1;
00202         
00203         if (Stage(6)) return(0);
00204     }   
00205     
00206     if (Stage(7)) return(0);
00207     
00208     return(1);
00209 }
00210 
00211 #ifdef RAD_VIS
00212 
00213 Void ProgRad::DumpStats(){}
00214 
00215 Int ProgRad::Stage(Int stage)
00216 {
00217     Int     i, j;
00218     Bool    animate = gRadControl->animate || gRadControl->pause;
00219 
00220     switch (stage)
00221     {
00222     case 1:     // pre setup
00223         Field(out3) << patches.NumItems() << " patches"  << show;
00224         Field(out1) << "Forming emission vector E..." << show;
00225         FFRows.Clear();
00226         if (gRadControl->drawMatrix)
00227         {
00228             FFRows.SetSize(patches.NumItems());
00229 //          FFRows.ClearTo(ColourList());
00230         }
00231         StartUpdate();
00232         break;
00233     case 2:     // post setup
00234         ColourVertices();
00235         display->Redraw();
00236 
00237         doUpdate = animate || Update();
00238 
00239         if (animate)
00240             Field(out1) << "Finding patch to shoot..." << show;
00241         else if (doUpdate)
00242         {
00243             Char *plural;
00244 
00245             if (iterations == 1)
00246                 plural = "";
00247             else
00248                 plural = "es";
00249 
00250             Field(out1) << iterations << " patch" << plural << " shot" << show;
00251 
00252             RenderMatrix();
00253         }
00254         break;
00255         
00256     case 3:     
00257         if (animate)
00258             Field(out1) << "Patch " << maxPowerIndex << " next to shoot"
00259                         << show;
00260         break;
00261         
00262     case 4:     // After patch setup
00263         if (doUpdate)
00264         {
00265             if (animate)           
00266             {
00267                 Field(out1) << "Calculating form factors..." << show;
00268                 // flash shooting patch red
00269                 patches[maxPowerIndex]->SetHighlight(1);
00270             }
00271 
00272             ColourVertices();
00273             
00274             display->Redraw();
00275             patches[maxPowerIndex]->SetHighlight(0);
00276         }
00277         break;
00278         
00279     case 5: 
00280         // Update our display matrix...
00281         if (doUpdate)
00282         {
00283             RenderMatrix();
00284             if (animate)
00285                 Field(out1) << "Shooting Patch " << maxPowerIndex << show;
00286         }
00287         break;
00288         
00289     case 6:     // Middle of solve loop.
00290             
00291         if (doUpdate)
00292         {
00293             // Colour the patches...
00294             for (i = 0; i < patches.NumItems(); i++)
00295             {
00296                 // Show the shot vector or the radiosity vector?
00297     
00298                 if (gRadControl->shotDisplay)                   
00299                     patches[i]->colour = S[i];
00300                 else
00301                     patches[i]->colour = B[i] + patches[i]->Reflectance() 
00302                         * envRad;
00303             }
00304     
00305             ColourVertices();
00306             display->Redraw();
00307             
00308             Field(out2) << "error = " << maxPower / origShoot
00309                         << ", RMS Error = " << error << show;
00310             UpdateCont();
00311         }
00312         break;
00313         
00314     case 7:
00315         // Colour the patches...
00316         for (i = 0; i < patches.NumItems(); i++)
00317             if (gRadControl->shotDisplay)                   
00318                 patches[i]->colour = S[i];
00319             else
00320                 patches[i]->colour = B[i] + patches[i]->Reflectance() * envRad;
00321 
00322         ColourVertices();
00323         display->Redraw();
00324         
00325         Field(out2) << "error = " << maxPower / origShoot << ", RMS Error = "
00326                     << error << show;
00327         Field(out1) << "Finished: " << iterations << " patches shot" << show;
00328         break;
00329     }
00330     return(Pause());
00331 }
00332 
00333 #else
00334 
00335 Void ProgRad::DumpStats()
00336 {
00337     Int     i;
00338     GCLReal shotErr, mem;
00339 
00340     if (origShoot == 0.0)
00341         shotErr = 1.0;
00342     else
00343         shotErr = maxPower / origShoot;
00344     
00345     mem = sizeof(Colour) * (B.NumItems() + S.NumItems() + FFRow.NumItems());
00346     mem /= 1024.0;
00347     
00348     cout << dumpID 
00349         << ' ' << totTime 
00350         << ' ' << gRadControl->stage 
00351         << ' ' << patches.NumItems() 
00352         << ' ' << shotErr
00353         << ' ' << error
00354         << ' ' << gRadControl->rays
00355         << ' ' << iterations 
00356         << ' ' << mem
00357         << ' ' << grid->MemoryUsage()
00358         << ' ' << TotalMemoryUse()
00359         << endl;
00360 
00361     for (i = 0; i < patches.NumItems(); i++)        // Colour the patches...
00362     {
00363         // Show the shot vector or the radiosity vector?
00364 
00365         if (gRadControl->shotDisplay)           
00366             patches[i]->colour = S[i];
00367         else
00368             patches[i]->colour = B[i] + patches[i]->Reflectance() * envRad;
00369     }
00370 
00371     DumpScene();
00372 }
00373 
00374 Int ProgRad::Stage(Int stage)
00375 {
00376     if (CheckTime()) return(1);
00377 
00378     gRadControl->stage = stage;
00379 
00380     switch (stage)
00381     {
00382     case 1:     // pre setup
00383         cout << "method prog " << endl;
00384         cout << "sub " << gRadControl->patchSubdivs << endl;
00385         cout << "tErr " << gRadControl->error << endl;
00386         cout << "scene " << sceneName << endl;
00387         cout << "polys " << gRadControl->numPolys << endl;
00388         cout << "srcPatches " << patches.NumItems() << endl;
00389         cout << "format "
00390              << "ID "
00391              << "time "
00392              << "stage "
00393              << "patches "
00394              << "shootErr "
00395              << "resErr "
00396              << "rays "
00397              << "iterations "
00398              << "mem "
00399              << "rtMem "
00400              << "rss "
00401              << endl;
00402 
00403         cout << "----------------------------------------------"
00404              << "---------------------------------" << endl;
00405     
00406         DumpStats();
00407         break;
00408         
00409     case 7:
00410         DumpStats();
00411         break;
00412     }
00413 
00414     if (Idle()) return(0);
00415     timer.ContTimer();
00416     return(0);
00417 }
00418 
00419 #endif
00420 
00421 Void ProgRad::DrawMatrix(Renderer &r)
00422 {
00423     if (!gRadControl->drawMatrix || gRadControl->stop)
00424         return;
00425         
00426 #ifdef RAD_VIS
00427     Int     i, j;
00428     GCLReal x1, x2, y1, y2, wx, wy;
00429         
00430     wx = 2.0 / FFRows.NumItems();
00431     
00432     x1 = -1;
00433     x2 = wx - 1;
00434     
00435     for (i = 0; i < FFRows.NumItems(); i++)
00436     {
00437         wy = 2.0 / FFRows[i].NumItems();
00438         y1 = 1 - wy;
00439         y2 = 1;
00440         
00441         for (j = 0; j < FFRows[i].NumItems(); j++)
00442         {
00443             if (patches[j]->highlight == 2 && patches[i]->highlight == 3)
00444                 r.C(cPurple);
00445             else if (patches[j]->highlight == 2)
00446                 r.C(cYellow);
00447             else if (patches[i]->highlight == 3)
00448                 r.C(cGreen);
00449             else    
00450                 r.SetColour(FFRows.NumItems() * FFRows[i][j]);
00451             PaintRect(r, Coord(x1, y1), Coord(x2, y2)); 
00452 
00453             y1 -= wy;
00454             y2 -= wy;
00455         }
00456         
00457         x1 += wx;
00458         x2 += wx;
00459     }
00460 #endif
00461 }
00462 
00463 
00464 RadElem *ProgRad::NewMesh()
00465 {
00466     return(new RadGrid());
00467 }

Generated at Sat Aug 5 00:26:52 2000 for Radiator by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000