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

HierRad.cc

Go to the documentation of this file.
00001 /*
00002 File: HierRad.cc
00003 
00004 Function: See header file
00005 
00006 Author(s): Andrew Willmott
00007 
00008 Copyright: (c) 1997-2000, Andrew Willmott
00009 
00010 Notes: 
00011 */
00012 
00031 #include "HierRad.h"
00032 #include "GenLink.h"
00033 #include "Haar.h"
00034 #include <stdio.h>
00035 #include <unistd.h>
00036 
00037 
00038 
00039 #ifdef RAD_VIS
00040 #include <strstream.h>
00041 #endif
00042 
00043 #ifdef DEBUG
00044 #define DBG_COUT if (1) cerr
00045 #define DBG_COUT2 if (0) cerr
00046 #else
00047  #define DBG_COUT if (0) cerr
00048  #define DBG_COUT2 if (0) cerr
00049 #endif
00050 
00051  HierRad::HierRad() : RadMethod(), cluster(0), leaves(0)
00052 {
00053 }
00054 
00055  HierRad::~HierRad()
00056 {
00057 delete cluster;
00058 delete leaves;
00059 }
00060 
00061  Void HierRad::SetScene(scScenePtr theScene)
00062 {
00063 Int i;
00064 
00065 DBG_COUT << "setting HR scene..." << endl;
00066 
00067 
00068 clusterableElems.Clear();
00069 
00070 RadMethod::SetScene(theScene); // this calls ResetOptions too
00071 
00072 // we don't do any remeshing, so collect stats here.
00073 
00074 stats.Init();
00075 for (i = 0; i < baseElems.NumItems(); i++)
00076 stats.Update(baseElems[i]);
00077 #ifdef DEBUG
00078 stats.Report(cerr);
00079 #endif
00080 }
00081 
00082  Void HierRad::ResetOptions()
00083 {
00084 Int i, j;
00085 
00086 gRadControl->finalPass = false;
00087 
00088 if (clusterableElems.NumItems() > 0 
00089 )
00090 {
00091 DBG_COUT << "resetting existing elements" << endl;
00092 
00093 // delete any previous meshing/clusters/etc.
00094 for (i = clusterableElems.NumItems() - 1; i >= 0; i--)
00095 clusterableElems[i]->Reset(); 
00096 if (cluster)
00097 cluster->Reset();
00098 }
00099 else
00100 {
00101 DBG_COUT << "creating elements" << endl;
00102 
00103 delete cluster;
00104 cluster = 0;
00105 
00106 // XXX cluster + higher order not supported yet.
00107 if (gRadControl->basis > kHaar)
00108 gRadControl->cluster = false;
00109 
00110 // add patches to the elements list
00111 DBG_COUT << "base elems = " << baseElems.NumItems() << endl;
00112 clusterableElems.SetSize(baseElems.NumItems());
00113 // upcast from RadElem pointer to HRElem pointer; we can assume that
00114 // all patches are a subclass of HRMeshElem.
00115 for (i = 0; i < baseElems.NumItems(); i++)
00116 clusterableElems[i] = (HRElemPtr) (HRMeshElem*) baseElems[i];
00117 
00118 
00119 DBG_COUT << "total HR elems = " << clusterableElems.NumItems() << endl;
00120 }
00121 
00122 numTrees = 0;
00123 leaves = 0;
00124 
00125 ColourMeshInitial();
00126 ColourVertices();
00127 
00128 #ifdef RAD_VIS
00129 gRadControl->pvData = 0;
00130 Field(out1) << clusterableElems.NumItems() << " patch elements";
00131 Field(out1) << show;
00132 #endif
00133 }
00134 
00135 
00136  Void HierRad::Draw(Renderer &r)
00137 {
00138 Bool saveWire = gRadControl->wire;
00139 
00140 if (gRadControl->patchView && gRadControl->pvData)
00141 {
00142 // draw contributors to this element
00143 gRadControl->outlineClusters = true;
00144 gRadControl->pvData->DrawContributors(r); 
00145 gRadControl->outlineClusters = false;
00146 gRadControl->wire = true;
00147 }
00148 
00149 // draw traditional patches
00150 RadMethod::Draw(r);
00151 
00152 
00153 // draw cluster last if it exists, so as to get transparency effects
00154 if (gRadControl->cluster && cluster)
00155 cluster->DrawElem(r);
00156 
00157 gRadControl->wire = saveWire;
00158 }
00159 
00160  Void HierRad::DrawMatrix(Renderer &r)
00161 {
00162 #ifdef RAD_VIS
00163 if (numTrees == 0)
00164 return;
00165 
00166 
00167 if (!gRadControl->drawMatrix || gRadControl->stop
00168 || gRadControl->cluster)
00169 return;
00170 
00171 Int i;
00172 
00173 for (i = 0; i < numTrees; i++)
00174 trees[i]->DrawMatrix(r, numTrees);
00175 #endif
00176 }
00177 
00178  HRLink *HierRad::CreateLink()
00179 {
00180 HRLink *result;
00181 
00182 // Create a top-level link between two patches
00183 
00184 if (gRadControl->cluster)
00185 result = new GenLink;
00186 else if (gRadControl->basis == kHaar)
00187 result = new HaarLink;
00188 else
00189 _Error("(HierRad::CreateLink) Unsupported basis");
00190 
00191 return(result);
00192 }
00193 
00194 
00195 // --- Rendering methods ------------------------------------------------------
00196 
00197 // NOTE: All these routines return false if the render should
00198 // terminate.
00199 
00200  Bool HierRad::CreateClusterLink()
00201 // Cluster the scene, and create the single initial top-level
00202 // link.
00203 {
00204 HRLink *newLink;
00205 
00206 // Create cluster
00207 if (Stage(2)) return(false);
00208 if (!cluster)
00209 {
00210 cluster = new Cluster;
00211 cluster->SetElems(&clusterableElems);
00212 cluster->CreateHierarchy();
00213 }
00214 
00215 clusTree = cluster;
00216 trees = &clusTree;
00217 numTrees = 1;
00218 
00219 // Create single top-level link 
00220 linkPatch = 0;
00221 if (Stage(3)) return(false);
00222 
00223 newLink = new GenLink;
00224 
00225 newLink->MakeLink(cluster, cluster);
00226 cluster->links.Prepend(newLink);
00227 
00228 return(true);
00229 }
00230 
00231  Bool HierRad::CreateInitialPatchLinks()
00232 // Creates top-level links between initial base polygons
00233 {
00234 Int i, j;
00235 HRLink *newLink1, *newLink2;
00236 
00237 // We only want to test visibility once
00238 // between each pair of patches.
00239 
00240 numTrees = clusterableElems.NumItems();
00241 trees = (HRElemPtr*) clusterableElems.Ref();
00242 if (Stage(2)) return(false);
00243 
00244 for (i = 0; i < numTrees; i++)
00245 {
00246 linkPatch = i;
00247 if (Stage(3)) return(false);
00248 
00249 for (j = i + 1; j < numTrees; j++)
00250 {
00251 
00252 newLink1 = 0;
00253 if (trees[i]->EltRho() != cBlack)
00254 {
00255 // Add link from j -> i
00256 
00257 newLink1 = CreateLink();
00258 if (newLink1->MakeLink(trees[j], trees[i]))
00259 {
00260 DBG_COUT2 << "link " << trees[j]->id << " to " 
00261 << trees[i]->id << endl;
00262 trees[i]->links.Prepend(newLink1);
00263 }
00264 else
00265 {
00266 newLink1->FreeLink(newLink1);
00267 DBG_COUT << "top-level link REDACTED" << endl;
00268 continue; // don't bother with the other direction.
00269 }
00270 } 
00271 
00272 if (trees[j]->EltRho() != cBlack)
00273 {
00274 // Add link from i -> j, reusing i->j link visibility
00275 // if possible.
00276 
00277 newLink2 = CreateLink();
00278 if (newLink2->MakeLink(trees[i], trees[j], newLink1, true))
00279 {
00280 DBG_COUT2 << "link " << trees[i]->id 
00281 << " to " << trees[j]->id << endl;
00282 trees[j]->links.Prepend(newLink2);
00283 }
00284 else
00285 {
00286 DBG_COUT << "top-level link REDACTED" << endl;
00287 newLink2->FreeLink(newLink2);
00288 }
00289 } 
00290 } 
00291 }
00292 
00293 return(true);
00294 }
00295 
00296  Bool HierRad::TwoStageSolve()
00298 {
00299 Int i;
00300 GCLReal origErr;
00301 GCLReal resErr;
00302 
00303 origErr = 1.0;
00304 error = 1.0;
00305 gRadControl->refineLevels = 32;
00306 if (gRadControl->solver != sv_scheduled)
00307 iterations = 0;
00308 if (Stage(5)) return(false); 
00309 
00310 // Refine the links in the scene
00311 if (Stage(6)) return(false);
00312 for (i = 0; i < numTrees; i++)
00313 {
00314 linkPatch = i;
00315 if (Stage(7)) return(false);
00316 trees[i]->Refine();
00317 }
00318 
00319 #ifdef RAD_RESTART_FROM_EMITTERS
00320 if (gRadControl->solver == sv_scheduled && iterations > 0)
00321 {
00322 DBG_COUT << "resetting radiosities" << endl;
00323 
00324 for (i = 0; i < numTrees; i++)
00325 trees[i]->InitRad();
00326 }
00327 #endif
00328 
00329 // Solve for radiosities... 
00330 do
00331 {
00332 resErr = 0.0;
00333 if (Stage(5)) return(false);
00334 
00335 // Do a gather over the whole scene
00336 if (Stage(8)) return(false);
00337 for (i = 0; i < numTrees; i++)
00338 {
00339 poly = i;
00340 if (Stage(9)) return(false);
00341 #ifdef RAD_VIS
00342 // if (doUpdate && gRadControl->showLinks)
00343 // display->Clear().Draw(gRadControl->scene);
00344 #endif
00345 trees[i]->GatherAll();
00346 #ifdef RAD_VIS
00347 // if (doUpdate && gRadControl->showLinks)
00348 // display->Show();
00349 #endif
00350 }
00351 
00352 // Now reconstruct the basis functions with a push/pull.
00353 // Separating the gather and push/pull stages like
00354 // this is the equivalent of Jacobi iteration, which is
00355 // more memory and time consuming than Gauss Seidel. Our
00356 // experiments with Gauss Seidel have shown that it can
00357 // lead to some instability problems however, especially
00358 // when there are a small number of very bright lights.
00359 
00360 if (Stage(10)) return(false);
00361 for (i = 0; i < numTrees; i++)
00362 {
00363 poly = i;
00364 if (Stage(11)) return(false);
00365 trees[i]->ClearB();
00366 trees[i]->PushPull();
00367 resErr += abs(trees[i]->Error());
00368 }
00369 
00370 if (origErr == 1.0 && resErr > 0.0)
00371 origErr = resErr;
00372 error = resErr / origErr;
00373 if (!gRadControl->solver == sv_scheduled)
00374 iterations++;
00375 
00376 if (Stage(12)) return(false); 
00377 }
00378 while (gRadControl->solver != sv_scheduled && error > gRadControl->error); // UUU
00379 
00380 return(true);
00381 }
00382 
00383  Bool HierRad::MultiGridSolve()
00384 {
00385 Int i;
00386 Bool subdivided;
00387 GCLReal origErr;
00388 GCLReal resErr;
00389 
00390 // Here we mix a single refine stage with a single solve stage, and
00391 // repeat until all links have been fully refined.
00392 
00393 origErr = 1.0;
00394 error = 1.0;
00395 subdivided = true;
00396 iterations = 0;
00397 
00398 // make sure mixed clusters etc. are refined before we start...
00399 // a bit hacky...
00400 if (gRadControl->cluster)
00401 {
00402 Double save1 = gRadControl->kAError;
00403 Double save2 = gRadControl->kFError;
00404 
00405 gRadControl->refineLevels = 32;
00406 gRadControl->kAError = 1e9;
00407 gRadControl->kFError = 1e9;
00408 cluster->Refine();
00409 gRadControl->kAError = save1;
00410 gRadControl->kFError = save2;
00411 }
00412 
00413 // refine only one level at a time.
00414 gRadControl->refineLevels = 1;
00415 
00416 do
00417 {
00418 resErr = 0.0;
00419 iterations++;
00420 if (Stage(5)) return(false);
00421 
00422 // Do a gather over the whole scene
00423 if (Stage(8)) return(false);
00424 for (i = 0; i < numTrees; i++)
00425 {
00426 poly = i;
00427 if (Stage(9)) return(false);
00428 #ifdef RAD_VIS
00429 // if (doUpdate && gRadControl->showLinks)
00430 // display->Clear().Draw(gRadControl->scene);
00431 #endif
00432 trees[i]->GatherAll();
00433 #ifdef RAD_VIS
00434 // if (doUpdate && gRadControl->showLinks)
00435 // display->Show();
00436 #endif
00437 }
00438 
00439 // Push/pull
00440 if (Stage(10)) return(false);
00441 for (i = 0; i < numTrees; i++)
00442 {
00443 poly = i;
00444 if (Stage(11)) return(false);
00445 trees[i]->ClearB();
00446 trees[i]->PushPull();
00447 resErr += abs(trees[i]->Error());
00448 }
00449 
00450 if (origErr == 1.0)
00451 origErr = resErr;
00452 error = resErr / origErr;
00453 if (Stage(12)) return(false);
00454 
00455 if (!subdivided) // don't refine if we've subdivided all we can.
00456 continue;
00457 
00458 // Refine the links in the scene
00459 if (Stage(6)) return(false); 
00460 subdivided = false;
00461 for (i = 0; i < numTrees; i++)
00462 {
00463 linkPatch = i;
00464 if (Stage(7)) return(false);
00465 if (trees[i]->Refine())
00466 subdivided = true;
00467 }
00468 
00469 if (iterations > 30) break; // XXX
00470 }
00471 while ((gRadControl->refAllLinks && subdivided) || error > gRadControl->error);
00472 
00473 return(true);
00474 }
00475 
00476  Bool HierRad::ScheduledSolve()
00477 {
00478 GCLReal origErr;
00479 
00480 // Here we repeat a two stage solve, dropping epsilon by a
00481 // set amount on each occasion.
00482 
00483 origErr = gRadControl->kFError;
00484 iterations = 0;
00485 
00486 do
00487 {
00488 if (!TwoStageSolve()) return(false);
00489 iterations++;
00490 gRadControl->kFError /= gRadControl->alpha;
00491 #ifdef RAD_VIS
00492 Field(out1) << "epsilon = " << gRadControl->kFError << show; 
00493 #endif 
00494 } while (iterations < gRadControl->schedIterations && !Pause());
00495 
00496 gRadControl->kFError = origErr;
00497 
00498 return(true);
00499 }
00500 
00501  Bool HierRad::Render()
00504 {
00505 Bool result;
00506 Int i;
00507 
00508 // Initialisation
00509 
00510 gRadControl->useBF = !(gRadControl->solver == sv_twoStage);
00511 linksCreated = 0;
00512 linksCreatedLast = 0;
00513 
00514 if (gRadControl->basis != kHaar) 
00515 // turn off anchoring & balancing for non-haar meshes
00516 {
00517 gRadControl->anchor = false;
00518 gRadControl->graded = false;
00519 }
00520 
00521 RadMethod::Render();
00522 
00523 if (Stage(1)) return(false);
00524 
00525 // Set up initial emission of the patches
00526 if (gRadControl->cluster)
00527 result = CreateClusterLink();
00528 else
00529 result = CreateInitialPatchLinks();
00530 
00531 if (!result)
00532 return(false);
00533 
00534 for (i = 0; i < numTrees; i++)
00535 trees[i]->InitRad();
00536 
00537 if (Stage(4)) return(false);
00538 
00539 if (gRadControl->solver == sv_scheduled)
00540 result = ScheduledSolve();
00541 else if (gRadControl->solver == sv_interleaved)
00542 result = MultiGridSolve();
00543 else if (gRadControl->solver == sv_twoStage)
00544 result = TwoStageSolve();
00545 else
00546 _Error("Unknown solver algorithm");
00547 
00548 if (Stage(13)) return(false);
00549 
00550 return(result);
00551 }
00552 
00553 
00554 #ifdef RAD_VIS
00555 Void HierRad::DumpStats()
00556 {
00557 }
00558 
00559 Int HierRad::Stage(Int stage)
00560 {
00561 Int i;
00562 ostrstream outMsg;
00563 Char tempStr[256];
00564 Bool animate = gRadControl->animate || gRadControl->pause;
00565 
00566 switch (stage)
00567 {
00568 case 1: // pre setup
00569 Field(out2) << "Starting patches: " << numTrees << show;
00570 Field(out1) << "Initialising patches." << show;
00571 ColourVertices();
00572 StartUpdate();
00573 break;
00574 
00575 case 2: // create links (post setup)
00576 if (gRadControl->cluster)
00577 Field(out1) << "Creating clusters..." << show;
00578 else
00579 Field(out1) << "Creating links... " << show;
00580 ColourVertices();
00581 display->Redraw();
00582 break;
00583 
00584 case 3: // create a link 
00585 doUpdate = animate || Update();
00586 if (doUpdate)
00587 {
00588 RenderMatrix();
00589 if (animate)
00590 Field(out1) << "Creating links for element " << linkPatch 
00591 << "/" << numTrees << show;
00592 else
00593 Field(out1) << "Created " << linkPatch << " links out of "
00594 << numTrees << show;
00595 }
00596 break;
00597 
00598 case 4: // solve system with refinement
00599 Field(out1) << "Solving system with refinement" << show;
00600 ColourVertices();
00601 display->Redraw();
00602 break;
00603 
00604 case 5: // solve system iteration
00605 RenderMatrix();
00606 Field(out1) << "Starting iteration " << iterations << show;
00607 Field(out2) << "Iteration " << iterations << show;
00608 doUpdate = animate || Update();
00609 break;
00610 
00611 case 6: // refine links
00612 Field(out1) << "Refining links" << show;
00613 break;
00614 
00615 case 7: // refine 1 link
00616 doUpdate = animate || Update();
00617 if (doUpdate)
00618 {
00619 Field(out1) << "Refining links for element " << linkPatch << show;
00620 Field(out3) << "Total links created so far: " << linksCreated << show;
00621 RenderMatrix();
00622 }
00623 break;
00624 
00625 case 8: // gather
00626 Field(out1) << "Gathering radiosity" << show;
00627 ColourVertices();
00628 display->Redraw();
00629 break;
00630 
00631 case 9: // gather across 1 link
00632 doUpdate = animate || Update();
00633 if (doUpdate)
00634 {
00635 Field(out1) << "Gathering to element " << poly << show;
00636 ColourVertices();
00637 display->Redraw();
00638 }
00639 break;
00640 
00641 case 10: // push/pull
00642 Field(out1) << "Push/Pulling hierarchies" << show;
00643 break;
00644 
00645 case 11: // push/pull 1
00646 doUpdate = animate || Update();
00647 if (doUpdate)
00648 {
00649 Field(out1) << "Push/Pull element " << poly << show;
00650 ColourVertices();
00651 display->Redraw();
00652 }
00653 break; 
00654 
00655 case 12: // finish one system iteration
00656 {
00657 HRStats stats;
00658 
00659 ColourVertices();
00660 display->Redraw();
00661 
00662 stats.Init();
00663 for (i = 0; i < numTrees; i++)
00664 trees[i]->CalcStats(&stats);
00665 
00666 Field(out2) << "Overall error: " << error << show;
00667 
00668 outMsg << "Iterations: " << iterations << 
00669 ", patches: " << stats.numPatches;
00670 if (stats.numVolClusters > 0)
00671 outMsg << ", vc: " << stats.numVolClusters;
00672 if (stats.numFaceClusters > 0)
00673 outMsg << ", fc: " << stats.numFaceClusters;
00674 outMsg << ", links: " << stats.numLinks;
00675 memcpy(tempStr, outMsg.str(), outMsg.pcount());
00676 tempStr[outMsg.pcount()] = 0;
00677 
00678 Field(out3) << tempStr << show;
00679 }
00680 break;
00681 case 13: // all done
00682 Field(out1) << "Colouring models...." << show;
00683 gRadControl->finalPass = true;
00684 ColourVertices();
00685 Field(out1) << "Finished." << show;
00686 display->Redraw();
00687 break;
00688 
00689 }
00690 
00691 return(Pause());
00692 }
00693 
00694 #else
00695 
00696  static Char *tBasis[] = {"none", "haar", "f2", "f3", "m2", "m3"};
00697  static Int tBasisOrder[] = {0, 1, 2, 3, 2, 3};
00698 
00699  static GCLReal gAlpha = 0.0;
00700  static Int gLinks0 = 0;
00701 
00702  Void HierRad::DumpStats()
00703 {
00704 Int i, m = tBasisOrder[gRadControl->basis];
00705 GCLReal mem, linkMem, patchMem, volClusMem;
00706 HRStats stats;
00707 
00708 stats.Init();
00709 for (i = 0; i < numTrees; i++)
00710 trees[i]->CalcStats(&stats);
00711 
00712 // Calculate projected memory use
00713 #ifdef RAD_THEORY_MEM
00714 linkMem = sizeof(Void*) * 2 + sizeof(GCLReal) + sizeof(Colour) * 
00715 sqr(sqr(m));
00716 patchMem = sizeof(Void*) * 5 + sizeof(Colour) * sqr(m) * 2;
00717 // 4 children, one link list pointer, m colour coefficients * 2.
00718 faceClusMem = sizeof(Void*) * 2 + sizeof(Colour) * 6;
00719 // 2 children, 3 colour coeffs * 2 
00720 volClusMem = sizeof(Void*) * 8 + sizeof(Colour) * 2;
00721 // 8 children, 1 HRElem pointer, 1 colour coeffs * 2
00722 #else
00723 linkMem = sizeof(GenLink);
00724 patchMem = sizeof(HRMeshElem);
00725 volClusMem = sizeof(Cluster);
00726 #endif
00727 
00728 mem = linkMem * stats.numLinks
00729 + patchMem * stats.numPatches
00730 + volClusMem * stats.numVolClusters
00731 ; 
00732 
00733 
00734 mem /= 1024.0;
00735 
00736 if (gAlpha <= 0.0)
00737 gLinks0 = stats.numLinks;
00738 
00739 if (gAlpha < 0.0)
00740 gAlpha = stats.numLinks / sqr(gRadControl->numPolys);
00741 
00742 cout << dumpID
00743 << ' ' << totTime
00744 << ' ' << gRadControl->stage
00745 << ' ' << iterations
00746 << ' ' << stats.numPatches
00747 << ' ' << stats.numVolClusters
00748 << ' ' << stats.numLinks
00749 << ' ' << linksCreated
00750 << ' ' << gAlpha
00751 << ' ' << stats.numLinks - gLinks0
00752 
00753 << ' ' << error
00754 << ' ' << gRadControl->rays
00755 << ' ' << mem
00756 << ' ' << grid->MemoryUsage()
00757 << ' ' << TotalMemoryUse()
00758 << endl;
00759 
00760 DumpScene();
00761 }
00762 
00763  static Char *gSolverNames[] =
00764 {
00765 "twoStage",
00766 "interleaved",
00767 "scheduled",
00768 0
00769 };
00770 
00771  Int HierRad::Stage(Int stage)
00772 {
00773 if (CheckTime()) return(1);
00774 
00775 gRadControl->stage = stage;
00776 
00777 switch (stage)
00778 {
00779 case 2:
00780 cout << "method hier " << tBasis[gRadControl->basis] << endl;
00781 if (gRadControl->cluster) cout << "clustering" << endl;
00782 cout << "solver " << gSolverNames[gRadControl->solver] << endl;
00783 
00784 cout << "tErr " << gRadControl->error << endl;
00785 cout << "fErr " << gRadControl->kFError << endl;
00786 cout << "aErr " << gRadControl->kAError << endl;
00787 cout << "dErr " << gRadControl->dFError << endl;
00788 cout << "vErr " << gRadControl->visError << endl;
00789 cout << "scene " << sceneName << endl;
00790 cout << "polys " << gRadControl->numPolys << endl;
00791 cout << "srcPatches " << numTrees << endl;
00792 // must match with list in DumpStats
00793 cout << "format "
00794 << "ID "
00795 << "time "
00796 << "stage "
00797 << "iterations "
00798 << "patches "
00799 << "volClusters "
00800 << "links "
00801 << "totLinks "
00802 << "sparsity "
00803 << "newLinks "
00804 << "resErr "
00805 << "rays "
00806 << "mem "
00807 << "rtMem "
00808 << "rss "
00809 << endl;
00810 cout << "----------------------------------------"
00811 << "---------------------------------------" << endl;
00812 
00813 iterations = 0;
00814 error = 0;
00815 gRadControl->finalPass = false;
00816 DumpStats();
00817 break;
00818 
00819 case 4: 
00820 // At this point the first-pass linking has been done.
00821 gAlpha = -1.0; // signal the DumpStats procedure
00822 DumpStats();
00823 break;
00824 
00825 case 13:
00826 if (gRadControl->dumpTree)
00827 {
00828 ofstream s;
00829 cerr << "Saving final hierarchy as " << (gRadControl->outFile) + ".hier" << endl;
00830 s.open(StrConst(gRadControl->outFile) + ".hier");
00831 HRElem::out = &s;
00832 s << "# hierarchy dump for " << sceneName << endl;
00833 s << "# e <ID> <childID1> <childID2>... -> define element" << endl;
00834 s << "# l <fromID> <toID> -> define link" << endl;
00835 for (Int i = 0; i < numTrees; i++)
00836 trees[i]->DumpHierarchy(0);
00837 s.close();
00838 HRElem::out = &cout;
00839 }
00840 gRadControl->finalPass = true;
00841 DumpStats();
00842 timer.ContTimer();
00843 GetElements(); // final pass gets performed here.
00844 timer.StopTimer();
00845 totTime = timer.GetTimer();
00846 gRadControl->stage++;
00847 DumpStats();
00848 
00849 break;
00850 }
00851 
00852 if (Idle()) return(0);
00853 timer.ContTimer();
00854 return(0);
00855 }
00856 
00857 #endif
00858 
00859  RadElem *HierRad::NewMesh()
00860 {
00861 RadElem *elem;
00862 
00863 if (gRadControl->basis == kHaar)
00864 elem = new HaarElem();
00865 else
00866 _Error("(HierRad::NewMesh) Unhandled basis");
00867 
00868 return(elem);
00869 }
00870 
00871  Void HierRad::ColourVertices()
00872 {
00873 Int i, j, oldRays;
00874 ProgramTimer timer;
00875 // colour underlying mesh & models
00876 
00877 oldRays = gRadControl->rays;
00878 if (gRadControl->finalPass)
00879 {
00880 if (gRadControl->shotDisplay)
00881 gRadControl->showRays = true;
00882 timer.StartTimer();
00883 
00884 }
00885 
00886 // colour leaves
00887 if (gRadControl->finalPass && gRadControl->bestPass)
00888 for (i = 0; i < numTrees; i++)
00889 {
00890 ShadeInfo shadeInfo;
00891 
00892 trees[i]->DistributeColoursBest(shadeInfo);
00893 } 
00894 else
00895 for (i = 0; i < numTrees; i++)
00896 trees[i]->DistributeColours();
00897 
00898 for (i = 0; i < baseElems.NumItems(); i++)
00899 ((HRMeshElem*) baseElems[i])->HRCorrectLeaves();
00900 
00901 
00902 if (gRadControl->finalPass)
00903 {
00904 DBG_COUT << "Done doing final distribute : " << timer.GetTimer() << "s" << endl;
00905 DBG_COUT << "Cast " << gRadControl->rays - oldRays << " more rays." << endl;
00906 }
00907 
00908 // for meshes, as before...
00909 
00910 RadMethod::ColourVertices();
00911 }
00912 
00913 
00914  PatchList *HierRad::GetElements()
00915 {
00916 if (!leaves)
00917 {
00918 Int i, j, n, numSubElems, numSplitElems = 0;
00919 HierElemPtr subElems[5];
00920 
00921 ColourVertices();
00922 
00923 
00924 leaves = new PatchList;
00925 for (i = 0; i < baseElems.NumItems(); i++)
00926 ((HierElemPtr) baseElems[i])->CollectLeaves(*leaves);
00927 
00928 if (gRadControl->anchor)
00929 {
00930 n = leaves->NumItems();
00931 
00932 for (i = 0; i < n; i++)
00933 {
00934 ((HierElemPtr) leaves->Item(i))->SplitElement(numSubElems, subElems);
00935 
00936 if (numSubElems > 0)
00937 {
00938 numSplitElems++;
00939 
00940 leaves->Item(i) = subElems[0];
00941 for (j = 1; j < numSubElems; j++)
00942 leaves->Append(subElems[j]);
00943 }
00944 }
00945 }
00946 }
00947 
00948 return(leaves);
00949 }
00950 
00951  Void HierRad::PrintCmds(ostream &s) const
00952 {
00953 Int i;
00954 
00955 RadMethod::PrintCmds(s);
00956 
00957 }
00958 
00959  Bool HierRad::ParseCmd(StrConst str, istream &s)
00960 {
00961 // XXX broken at the mo'
00962 return(RadMethod::ParseCmd(str, s));
00963 }
00964 
00965 
00966 HRElem *HierRad::ClosestHRIntersection(Point &start, Point &dir, Point &p)
00967 {
00968 #ifdef RAD_VIS
00969 if (grid)
00970 {
00971 if (grid->ClosestIntersection(start, dir))
00972 {
00973 p = grid->hitT * dir + start;
00974 
00975 if (grid->hitPrim->object->id == 0)
00976 {
00977 if (rtElemPtrs.NumItems() > 0)
00978 return(dynamic_cast<HRMeshElem*>(rtElemPtrs[grid->hitPrim->id]));
00979 }
00980 }
00981 }
00982 #endif
00983 
00984 return(0);
00985 }

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

AltStyle によって変換されたページ (->オリジナル) /