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

RadVis.cc

Go to the documentation of this file.
00001 /*  
00002     File:           RadVis.cc
00003 
00004     Function:       GUI front end for the various radiosity methods. Allows 
00005                     visualisation of the methods.
00006                     
00007     Author(s):      Andrew Willmott
00008 
00009     Copyright:      (c) 1997-2000, Andrew Willmott
00010  */
00011 
00012 
00013 
00014 #include "TestScene.h"
00015 
00016 #include "MatRad.h"
00017 #include "ProgRad.h"
00018 #include "HProgRad.h"
00019 #include "HierRad.h"
00020 
00021 #include "RadPane.h"
00022 #include "RadScene.h"
00023 #include "Examiner.h"
00024 
00025 #include "gcl/XGraphicsSystem.h"
00026 #include "gcl/Forms.h"
00027 #include "gcl/SceneLang.h"
00028 #include "gcl/Avars.h"
00029 #include "gcl/Readers.h"
00030 #include "gcl/EPSRenderer.h"
00031 #include "gcl/MesaRenderer.h"
00032 
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include "cl/ArgParse.h"
00036 
00037 // classes derived from fdesign.
00038 #include "theForms.h"   
00039 
00040 class RadForm;
00041 
00042 // --- exponential slider -----------------------------------------------------
00043 
00044 // provides exponential-based slider more suited to error metrics
00045 // basically steps down through 0.9 .. 0.1, 0.09 .. 0.01, etc.
00046 
00047 static double eslider_map(double val)
00048 {
00049     double d = floor(val - 0.05);
00050 
00051     return(pow(10.0, d + 1.0) * (val - d));
00052 }
00053 
00054 static char *esliderFilt(FL_OBJECT *, double val, int prec)
00055 {
00056     static char result[32];
00057 
00058     val = eslider_map(val);
00059     sprintf(result, "%.*g", prec, val);
00060 
00061     return(result);
00062 }
00063 
00064 double fl_get_eslider_value(FL_OBJECT *obj)
00065 {
00066     return(eslider_map(fl_get_slider_value(obj)));
00067 }
00068 
00069 double fl_set_eslider_value(FL_OBJECT *obj, double val)
00070 {
00071 }
00072 
00073 // --- Options Panels --------------------------------------------------------
00074 
00075 
00076 class TransportPanel : public TransportForm
00077 {
00078 public:
00079     TransportPanel(RadForm *radform) : TransportForm(), parent(radform) {};
00080     
00081     Void    Event(FL_OBJECT *object);
00082         
00083     RadForm *parent;
00084 };
00085 
00086 class RenderPanel : public RenderForm
00087 {
00088 public:
00089     RenderPanel(RadForm *radform) : RenderForm(), parent(radform) {};
00090     
00091     Void    Event(FL_OBJECT *object);
00092         
00093     RadForm *parent;
00094 };
00095 
00096 
00097 // --- AvarPanel --------------------------------------------------------------
00098 
00099 
00100 class AvarPanel : public AvarForm
00101 {
00102 public:
00103     Void    Init();
00104     Void    Event(FL_OBJECT *object);
00105     Void    SetScene(scScenePtr scene);
00106     Void    Dump(ostream &s);
00107     
00108     scAvarList  *avarList;
00109     ScenePane   *scenePane;
00110 };
00111 
00112 Void AvarPanel::Init()
00113 {
00114     fl_set_slider_bounds(avarSlider, 0, 1); 
00115     fl_set_slider_value(avarSlider, 1); 
00116 }
00117 
00118 Void AvarPanel::SetScene(scScenePtr scene)
00119 {
00120     Int i;
00121     CreateAvarList avarGrabber;
00122     
00123     scene->ApplyAction(avarGrabber);
00124     avarList = avarGrabber.avarList;
00125     
00126     fl_clear_browser(avarBrowser);
00127     
00128     for (i = 0; i < avarList->NumItems(); i++)
00129         fl_add_browser_line(avarBrowser, (*avarList)[i].name);
00130 }
00131 
00132 Void AvarPanel::Dump(ostream &s)
00133 {
00134     Int i;
00135     
00136     for (i = 0; i < avarList->NumItems(); i++)
00137         cout << (*avarList)[i].name << " = " << (*avarList)[i].value << endl;
00138 }
00139 
00140 Void AvarPanel::Event(FL_OBJECT *object)
00141 {
00142     if (object == avarBrowser)
00143     {
00144         if (fl_get_browser(object) > 0)
00145         {
00146             Avar &avar = (*avarList)[fl_get_browser(avarBrowser) - 1];
00147             
00148             fl_set_slider_bounds(avarSlider, avar.upperBound,
00149                                  avar.lowerBound);  
00150             fl_set_slider_value(avarSlider, avar.value);    
00151         }
00152     }
00153     else if (object == avarSlider)
00154     {
00155         if (fl_get_browser(avarBrowser) > 0)
00156         {
00157             (*avarList)[fl_get_browser(avarBrowser) - 1].value = 
00158                 fl_get_slider_value(avarSlider);
00159             if (scenePane)
00160                 scenePane->Redraw();    
00161         }
00162     }
00163     else if (object == dismiss)
00164         Hide();
00165     else if (object == dump)
00166         Dump(cout);
00167 }
00168 
00169 
00170 // --- The radvis main pane! --------------------------------------------------
00171 
00172 
00173 class RadForm : public RadVisMainForm
00174 {
00175 public:
00176 
00177     RadForm();
00178         
00179     Int                     Main(Int argc, Char **argv);
00180     Void                    InitOptions(Int argc, Char **argv, 
00181                                     RadControl &options, Char **scenePathP);
00182 
00183     Void                    Event(FL_OBJECT *object);
00184     Void                    Init(const Char *scenePath);
00185     Void                    SetupControls();
00186     Void                    SetupMenus();
00187     Void                    SetFormOptions();
00188                             // set form controls from options field
00189     Void                    GetFormOptions();
00190                             // set options field from form controls 
00191 
00192     Void                    SamplePatch(Matd &samples);
00193     Void                    SampleFF(Matd &samples);
00194     Void                    UpdateMethodOptions(Int a, Int b);
00195     Void                    RenderMode(Bool on);
00196 
00197     Void                    UpdateRadScene();
00198     Void                    UpdateScene();
00199     scScenePtr              LoadScene();
00200     scScenePtr              LoadScene(const Char *path);
00201 
00202     // Commands
00203 
00204     Void                    Go();
00205     Void                    Reset();
00206     Void                    ChooseMethod();
00207     Void                    SceneSelect();
00208     Void                    DumpImage();
00209     Void                    DumpEPS();
00210     Void                    DumpObjFile();
00211     Void                    DumpSLFile();
00212     Void                    DumpCamera();
00213     Void                    StartHelp();
00214 
00215     // Fields
00216     
00217     Int                     oldMethodChoice;
00218         
00219     scScenePtr              scene;
00220     scScenePtr              matrixScene;
00221     RadMethod               *radMethod;
00222     RadControl              options;
00223     
00224     RadScenePane            mainPane;
00225     ScenePane2D             matrixPane;
00226 
00227     AvarPanel               avarPanel;
00228     TransportPanel          transPanel;
00229     RenderPanel             renderPanel;
00230     
00231     FormsGraphicsSystem     *fgs;
00232     Bool                    sceneSet;
00233     Colour                  bgColour;
00234 };
00235 
00236 
00237 // --- RadMethod form methods -------------------------------------------------------
00238 
00239 
00240 RadForm::RadForm() : 
00241     RadVisMainForm(),
00242     scene(0), 
00243     transPanel(this), 
00244     renderPanel(this), 
00245     fgs(0)
00246 { 
00247 #ifdef DEBUG
00248     title = "Radiosity Visualisation (Debug)";
00249 #else
00250     title = "Radiosity Visualisation";
00251 #endif
00252     gRadControl = &options;
00253 }
00254 
00255 Void RadForm::Init(const Char *scenePath)
00256 {   
00257     fgs->CreateFormsPane((XEventPane*) &mainPane, box1);
00258     fgs->CreateFormsPane(&matrixPane, box2);
00259     
00260     SetupControls();
00261     SetupMenus();
00262     SetFormOptions();
00263             
00264     //  Enable/Disable the right controls.
00265 
00266     UpdateMethodOptions(kMatrix, kNoMethod);
00267     UpdateMethodOptions(kProgressive, kNoMethod);
00268     UpdateMethodOptions(kProgSubstruct, kNoMethod);
00269     UpdateMethodOptions(kHierarchical, kNoMethod);
00270     UpdateMethodOptions(kAnalytical, kNoMethod);
00271     UpdateMethodOptions(kNoMethod, options.method);
00272     
00273     slInit();   
00274     if (scenePath)
00275         scene = LoadScene(scenePath);
00276     else
00277     {
00278         options.drawMatrix = true;
00279         options.cluster = false;
00280         scene = BoxScene();
00281     }
00282     
00283     // Set up the radiosity method and the view pane.
00284     
00285     mainPane.SetBgColour(bgColour);
00286     mainPane.SetParent(this);
00287     sceneSet = false;
00288     // get into 'reset' state...
00289     Reset();
00290 
00291     oldMethodChoice = 0;
00292     radMethod = RadMethod::NewRadMethod();
00293     radMethod->SetDisplay(&mainPane, fgs);
00294 
00295     radMethod->matDisplay = &matrixPane;
00296     radMethod->out1 = comment;
00297     radMethod->out2 = debug1;
00298     radMethod->out3 = debug2;
00299 
00300     matrixPane.SetBgColour(bgColour);
00301     matrixScene = slBeginObject("matrix");
00302     slObject(new scMatrixDisplay((Void **) &radMethod));
00303     slEndObject();
00304     matrixPane.SetScene(matrixScene);
00305     matrixPane.Redraw();
00306 }
00307 
00308 Void RadForm::SetupMenus()
00309 {
00310     // Set up the menus
00311 
00312     fl_set_choice_fontsize(methodChoice, FL_SMALL_SIZE);
00313     fl_set_choice_fontstyle(methodChoice, FL_BOLD_STYLE);
00314     fl_set_choice_fontsize(basis, FL_SMALL_SIZE);
00315     fl_set_choice_fontstyle(basis, FL_BOLD_STYLE);
00316     fl_set_choice_fontsize(transPanel.visMethod, FL_TINY_SIZE);
00317     fl_set_choice_fontsize(transPanel.quadLevel, FL_TINY_SIZE);
00318 }
00319 
00320 Void RadForm::SetupControls()
00321 {
00322     // Set values for the various UI components
00323             
00324     fl_set_slider_bounds(patchSubdivs, 0.0, 20);    
00325     fl_set_slider_value(patchSubdivs, 1.0); 
00326     fl_set_slider_return(patchSubdivs, 0);  
00327     
00328     fl_set_slider_bounds(eltSubdivs, 0.2, 20);  
00329     fl_set_slider_value(eltSubdivs, 0.5);
00330     fl_set_slider_return(eltSubdivs, 0);
00331     
00332     fl_set_slider_bounds(alphaLevel, 1, 2); 
00333     fl_set_slider_value(alphaLevel, 1); 
00334     fl_set_slider_return(alphaLevel, 0);
00335     
00336     fl_set_slider_bounds(error, -7.0, 0.0);
00337     fl_set_slider_step(error, 0.1);
00338     fl_set_slider_precision(error, 4);
00339     fl_set_slider_filter(error, esliderFilt);
00340     fl_set_slider_value(error, -3.0);
00341 
00342     fl_set_slider_bounds(kFError, -7.0, 0.0);
00343     fl_set_slider_step(kFError, 0.1);
00344     fl_set_slider_precision(kFError, 4);
00345     fl_set_slider_filter(kFError, esliderFilt);
00346     fl_set_slider_value(kFError, -2.0);
00347     
00348     fl_set_slider_bounds(kAError, -7.0, 2.0);
00349     fl_set_slider_step(kAError, 0.1);
00350     fl_set_slider_precision(kAError, 4);
00351     fl_set_slider_filter(kAError, esliderFilt);
00352     fl_set_slider_value(kAError, -6.0);
00353 
00354     fl_set_counter_bounds(plotRes, 1, 32);
00355     fl_set_counter_step(plotRes, 1, 1);
00356     fl_set_counter_value(plotRes, 6);
00357     
00358     fl_set_counter_bounds(renderPanel.maxIter, 1, 16);
00359     fl_set_counter_step(renderPanel.maxIter, 1, 1);
00360     fl_set_counter_bounds(renderPanel.bestLevels, -1, 8);
00361     fl_set_counter_step(renderPanel.bestLevels, 1, 1);
00362 
00363     my_deactivate(examRad);     // Deactivate plot buttons.
00364     my_deactivate(examFF);
00365 }
00366 
00367 #include "SetGet.cc"
00368 
00369 Void RadForm::SampleFF(Matd &samples)
00370 // Sample the form factor values from the currently selected source patch over
00371 // the currently selected destination patch.
00372 {
00373     Int         i, j;
00374     RadElem     *to = mainPane.selPatch[0];
00375     RadElem     *from = mainPane.selPatch[1];
00376     Coord       place;
00377     Vector      x, y;
00378     Point       point;
00379     Int         density;
00380     
00381     if (options.method == kHierarchical && 
00382             (options.basis == kFlatlet3 || options.basis == kMultiwavelet3))
00383         density = (Int) (fl_get_counter_value(plotRes) * 3);
00384     else
00385         density = (Int) (fl_get_counter_value(plotRes) * 4);
00386     
00387     samples.SetSize(density + 1, density + 1);
00388     x = to->Vertex(2) - to->Vertex(1);
00389     y = to->Vertex(0) - to->Vertex(1);
00390         
00391     for (i = 0; i <= density; i++)
00392         for (j = 0; j <= density; j++)
00393         {
00394             if (i == 0)
00395                 place[0] = 1e-6;
00396             else
00397                 place[0] = i / GCLReal(density) - 1e-6;
00398 
00399             if (j == 0)
00400                 place[1] = 1e-6;
00401             else
00402                 place[1] = j / GCLReal(density) - 1e-6;
00403             
00404             point = x * place[0] + y * place[1] + to->Vertex(1);
00405             samples[i][j] = 
00406                 from->ApproxPatchFactor(point, to->Normal());
00407         }
00408 }
00409 
00410 Void RadForm::SamplePatch(Matd &samples)
00411 // Sample the currently selected patch.
00412 {
00413     Int         i, j;
00414     RadElem     *leaf;
00415     Coord       place;
00416     Int         density;
00417     
00418     if (options.method == kHierarchical && (options.basis == kFlatlet3 ||
00419                                             options.basis == kMultiwavelet3))
00420         density = (Int) fl_get_counter_value(plotRes) * 9;
00421     else
00422         density = (Int) fl_get_counter_value(plotRes) * 8;
00423 
00424     samples.SetSize(density, density);
00425         
00426     for (i = 0; i < density; i++)
00427         for (j = 0; j < density; j++)
00428         {
00429             place[0] = GCLReal(i) / GCLReal(density - 1);
00430             place[1] = GCLReal(j) / GCLReal(density - 1);
00431                         
00432             samples[i][j] =  len((mainPane.selPatch[0])->Sample(place));
00433         }
00434 }
00435 
00436 
00437 Void RadForm::UpdateMethodOptions(Int oldMethod, Int newMethod)
00438 {
00439     switch (oldMethod)
00440     {
00441     case kMatrix:
00442         my_deactivate(alphaLevel);
00443         my_deactivate(patchSubdivs);
00444         break;
00445     case kProgressive:
00446         my_deactivate(alphaLevel);
00447         my_deactivate(patchSubdivs);
00448         my_deactivate(error);
00449         break;
00450     case kProgSubstruct:
00451         my_deactivate(error);
00452         my_deactivate(alphaLevel);
00453         my_deactivate(eltSubdivs);
00454         my_deactivate(patchSubdivs);
00455         my_deactivate(kFError);
00456         my_deactivate(kAError);
00457         break;
00458     case kHierarchical:
00459         my_deactivate(alphaLevel);
00460         my_deactivate(basis);
00461         my_deactivate(error);
00462         my_deactivate(kFError);
00463         my_deactivate(kAError);
00464         break;
00465     case kAnalytical:
00466         my_deactivate(patchSubdivs);
00467         break;
00468     }
00469         
00470     switch (newMethod)
00471     {
00472     case kMatrix:
00473         my_activate(alphaLevel);
00474         my_activate(patchSubdivs);
00475         break;
00476     case kProgressive:
00477         my_activate(alphaLevel);
00478         my_activate(patchSubdivs);
00479         my_activate(error);
00480         break;
00481     case kProgSubstruct:
00482         my_activate(error);
00483         my_activate(alphaLevel);
00484         my_activate(eltSubdivs);
00485         my_activate(patchSubdivs);
00486         my_activate(kFError);
00487         my_activate(kAError);
00488         break;
00489     case kHierarchical:
00490         my_activate(alphaLevel);
00491         my_deactivate(basis); 
00492         my_activate(error);
00493         my_activate(kFError);
00494         my_activate(kAError);
00495         break;
00496     case kAnalytical:
00497         my_activate(patchSubdivs);
00498     }
00499 }
00500 
00501 Void RadForm::RenderMode(Bool on)
00502 {
00503     if (!on)
00504     {
00505         UpdateMethodOptions(kNoMethod, options.method);
00506         my_activate(goBtn);
00507         my_activate(avar);
00508         my_activate(exitBtn);
00509         my_activate(methodChoice);
00510     }
00511     else
00512     {
00513         UpdateMethodOptions(options.method, kNoMethod);
00514         my_deactivate(goBtn);
00515         my_deactivate(avar);
00516         my_deactivate(exitBtn);
00517         my_deactivate(methodChoice);
00518     }
00519 }
00520 
00521 scScenePtr RadForm::LoadScene()
00522 {
00523     const Char *result;
00524 
00525     result = fl_show_fselector("Please pick a scene file", 0, "*.*", 0);
00526     return(LoadScene(result));
00527 }
00528 
00529 scScenePtr RadForm::LoadScene(const Char *path)
00530 {
00531     scScenePtr  scene = 0;
00532     FileName    filename;
00533     
00534     if (path)
00535     {
00536         filename.SetPath(path);
00537         scene = SceneReader::Load(filename);
00538         if (scene)
00539             scene->Normalise();
00540     }
00541 
00542     if (!scene)
00543         scene = BoxScene();
00544         
00545     return(scene);
00546 }
00547 
00548 // --- Event Handling ---------------------------------------------------------
00549 
00550 static const Char *gHelpURL = 
00551         "http://www.cs.cmu.edu/~radiosity/radvis-help.html";
00552 
00553 Void RadForm::StartHelp()
00554 {
00555     String      line;
00556     Int         err;
00557     StatusForm  status;
00558     Char        *netscape = "netscape";
00559     
00560     // Fire up nutscape, if necessary, and target the help URL.
00561     // XXX Should change this to use exec*() and wait()...
00562     
00563     status.Show();
00564     Field(status.heading) << "Help" << show;
00565     Field(status.body) << "Opening " << gHelpURL << show;
00566     line.Printf("%s -remote 'openURL(%s, new-window)'", netscape, gHelpURL);
00567     err = system(line);
00568 
00569     if (err)
00570     {
00571         Field(status.body) << "remote failed (" << err << ")" << show;
00572         line.Printf("%s %s&", netscape, gHelpURL);
00573         Field(status.body) << "Starting Netscape..." << show;
00574         err = system(line);
00575         if (err)
00576             cout << "Could not invoke Netscape: help is available at "
00577                  << gHelpURL << show;
00578         else
00579             Field(status.body) << "All systems go..." << show;
00580     }
00581     else
00582         Field(status.body) << "All systems go." << show;
00583     
00584     sleep(2);
00585     status.Hide();
00586 }
00587 
00588 Void RadForm::UpdateRadScene()
00589 {
00590     GetFormOptions();
00591 
00592     Int saveWire = options.wire;
00593     options.wire = true;
00594     if (!sceneSet)
00595     {
00596         radMethod->SetScene(scene);
00597         mainPane.SetHeadlight(false);
00598         mainPane.SetScene(radMethod->GetScene());
00599     }
00600     else
00601         radMethod->ResetOptions();
00602 
00603     mainPane.Redraw();
00604     options.wire = saveWire;
00605     sceneSet = true;
00606 
00607     SetFormOptions();
00608 }
00609 
00610 Void RadForm::ChooseMethod()
00611 {
00612     // Change the selected radiosity method
00613     
00614     if (oldMethodChoice != fl_get_choice(methodChoice))
00615     {
00616         delete radMethod;
00617         UpdateMethodOptions(oldMethodChoice, fl_get_choice(methodChoice));
00618 
00619         GetFormOptions();
00620         radMethod = RadMethod::NewRadMethod();
00621         radMethod->SetDisplay(&mainPane, fgs);
00622         radMethod->matDisplay = &matrixPane;
00623         radMethod->out1 = comment;
00624         radMethod->out2 = debug1;
00625         radMethod->out3 = debug2;
00626 
00627         if (options.method >= kHierarchical)
00628             options.visibility = vis_4x4;
00629         else
00630             options.visibility = vis_1;
00631 
00632         sceneSet = false;
00633         Reset();
00634         oldMethodChoice = fl_get_choice(methodChoice);
00635     }
00636 }
00637 
00638 Void RadForm::Reset()
00639 {
00640     // reset the current radiosity run
00641         
00642     options.stop = true;
00643     options.step = false;
00644     options.pause = false;
00645     options.pvData = 0;
00646     my_deactivate(examRad);     // Deactivate plot buttons.
00647     my_deactivate(examFF);
00648     fl_set_button(pause, options.pause);
00649 
00650     // go back to the original scene.
00651 
00652     sceneSet = false;
00653     mainPane.SetHeadlight(true);
00654     mainPane.SetScene(scene);
00655     avarPanel.scenePane = 0;
00656     Field(comment) << "Current scene: " << scene->Label() << show;
00657     SetFormOptions();
00658 }
00659 
00660 Void RadForm::Go()
00661 {
00662     // Render the current scene.
00663                 
00664     RenderMode(true);
00665     options.stop = false;
00666 
00667     // Make sure the scene has been attached to the renderer.
00668 
00669     UpdateRadScene();
00670 //  avarPanel.Hide(); XXX need to fix xforms error msg before we can
00671 //  do this.
00672 
00673     // Doooo it...
00674 
00675     radMethod->Render();
00676 
00677     RenderMode(false);
00678 }
00679 
00680 Void RadForm::SceneSelect()
00681 {
00682     // we default to showing the matrix, and no volume clustering
00683     // for simple scenes. 
00684     options.drawMatrix = true;
00685     options.cluster = false;
00686 
00687     switch(fl_get_choice(sceneSelect))
00688     {
00689     case 1:
00690         scene = BoxScene(); break;
00691     case 2:
00692         scene = ParallelScene(); break;
00693     case 3:
00694         scene = SidelightScene(); break;
00695     case 4:
00696         scene = BlockerScene(); break;
00697     case 5:
00698         scene = AbuttingScene(); break;
00699     case 6:
00700         scene = TableScene();
00701         options.drawMatrix = false;
00702         options.cluster = true;
00703         break;
00704     case 7:
00705         scene = BoxScene(1); break;
00706     default:
00707         scene = LoadScene(); 
00708         options.drawMatrix = false;
00709         options.cluster = true;
00710         break;
00711     }
00712         
00713     sceneSet = false;
00714     Reset();
00715 }
00716 
00717 Void RadForm::DumpImage()
00718 {
00719     const Char  *result;
00720     RGBAImage   image;
00721     FileName    imageFile;
00722     
00723     result = fl_show_fselector("Saving main image...", 0, "*.tiff,*.tif,*.ppm",
00724                                "radvis.tif");
00725     mainPane.Redraw();
00726 
00727     if (result)
00728     {
00729         imageFile.SetPath(result);
00730         imageFile.MakeUnique();
00731         cout << "*** dumping image to " << result << endl;
00732 
00733 #ifdef GCL_MESA
00734         MesaRenderer    mr;
00735         RGBAImage       hqImage;
00736         Int             xsize = 400, ysize = 400;
00737                 
00738         image.SetSize(2 * xsize, 2 * ysize);
00739         hqImage.SetSize(xsize, ysize);
00740         mr.Init(image);
00741         mr.SetHeadlight(false);
00742         mr.SetDoubleSided(true);
00743         mr.SetBgColour(bgColour);
00744         mr.Clear().Draw(mainPane.ItsScene()).Show();
00745         image.DownSample(hqImage);
00746 
00747         hqImage.Save(imageFile);
00748 #else
00749         mainPane.GetImage(image);
00750         image.Save(imageFile);
00751 #endif
00752     }   
00753 }
00754 
00755 Void RadForm::DumpObjFile()
00756 {
00757     const Char  *result;
00758 
00759     result = fl_show_fselector("Saving wavefront file...", 0, "*.obj,*.obj.gz",
00760                                "radvis.obj");
00761     mainPane.Redraw();
00762 
00763     if (result)
00764     {
00765         cout << "*** dumping wavefront file to " << result << endl;
00766 
00767         radMethod->WriteObjFile(FileName().SetPath(result).MakeUnique().GetPath());
00768     }   
00769 }
00770 
00771 Void RadForm::DumpSLFile()
00772 {
00773     const Char  *result;
00774 
00775     result = fl_show_fselector("Saving SL file...", 0, "*.sl",
00776                                "out.sl");
00777     mainPane.Redraw();
00778 
00779     if (result)
00780     {
00781         cout << "*** dumping GCL 'SL' file to " << result << endl;
00782 
00783         radMethod->WriteSLFile(result);
00784     }   
00785 }
00786 
00787 Void RadForm::DumpEPS()
00788 {
00789     const Char  *result;
00790     ofstream    fout;
00791 
00792     result = fl_show_fselector("Saving main image...", 0, "*.eps", "radvis.eps");
00793 
00794     if (result)
00795     {
00796         EPSRenderer eps;
00797         cout << "*** dumping eps file to " << result << endl;
00798             
00799         eps.Attach(FileName().SetPath(result).MakeUnique().GetPath());
00800         eps.Clear().Draw(mainPane.ItsScene()).Show();
00801     }           
00802 }
00803 
00804 Void RadForm::DumpCamera()
00805 {
00806     const Char *result;
00807     ofstream    fout;
00808         
00809     result = fl_show_fselector(
00810         "Saving camera file...", 0, "*.cam", "out.cam");
00811         
00812     if (result)
00813     {
00814         cout << "*** saving camera to " << result << endl;
00815         fout.open(result);
00816         if (fout)
00817             ((scCamera*) mainPane.ItsCamera())->Print(fout);
00818         else
00819             perror("Couldn't open output file");
00820     }
00821 
00822 
00823 }
00824 
00825 Void RadForm::Event(FL_OBJECT *object)
00826 {
00827     // Handle UI events. This should be split out into (many) different
00828     // routines!
00829 
00830     if (object == exitBtn)
00831     {
00832         // Our work here is done.       
00833         fgs->SignalDone();
00834     }
00835     else if (object == goBtn)
00836         Go();
00837     else if (object == methodChoice)
00838         ChooseMethod();
00839     else if (object == resetBtn)
00840         Reset();
00841     else if (object == step)
00842     {
00843         options.step = true;
00844         options.pause = true;
00845         fl_set_button(pause, options.pause);
00846     }
00847     else if (object == sceneSelect)
00848         SceneSelect();
00849     else if (object == save)
00850     {
00851         switch(fl_get_menu(save))
00852         {
00853         case 1:
00854             DumpImage();
00855             break;
00856         case 2:
00857             DumpEPS();
00858             break;
00859         case 3:
00860             DumpSLFile();
00861             break;
00862         case 4:
00863             DumpObjFile();
00864         }
00865     }
00866     else if (
00867         object == gouraudBtn ||
00868         object == textureBtn ||
00869         object == wireFrame || 
00870         object == patchView ||
00871         object == funcView || 
00872         object == anchor ||
00873         object == animation 
00874         )
00875     {
00876         // These are option-changing controls: we update the options and redraw
00877         // the scene in case it or the way of drawing it has changed.
00878     
00879         GetFormOptions();
00880         mainPane.Redraw();  
00881 
00882     }
00883     if (object == methodOpts)
00884     {
00885         Int item = fl_get_menu(methodOpts);
00886         if (item == 9)
00887         {   
00888             renderPanel.Show();
00889             return;
00890         }
00891 
00892         GetFormOptions();
00893     }
00894     else if (
00895             object == patchSubdivs ||
00896             object == eltSubdivs
00897         )
00898     {
00899         // notify rad object that meshing parameters have changed
00900         UpdateRadScene();
00901     }
00902     else if (object == avar)
00903     {
00904         sceneSet = false;
00905         Reset();
00906         
00907         //  Show the avar panel
00908         
00909         avarPanel.Show();
00910         if (avarPanel.scenePane == 0)
00911         {
00912             avarPanel.SetScene(scene);
00913             avarPanel.scenePane = &mainPane;
00914             scene->Set(avarPanel.avarList);
00915             avarPanel.Init();
00916         }
00917     }
00918     else if (object == examRad && mainPane.selPatch[0])
00919     {
00920         Examiner *newPlot = new Examiner;
00921         
00922         newPlot->Show();
00923         newPlot->Init(*fgs, &mainPane);
00924         SamplePatch(newPlot->plot->samples);
00925         newPlot->plotPane.SetBgColour(bgColour);
00926         newPlot->plotPane.Redraw();
00927     }
00928     else if (object == examFF && mainPane.selPatch[0] && mainPane.selPatch[1])
00929     {
00930         Examiner *newPlot = new Examiner;
00931         
00932         newPlot->Show();
00933         newPlot->Init(*fgs, &mainPane);
00934         newPlot->plotPane.SetBgColour(bgColour);
00935         SampleFF(newPlot->plot->samples);
00936         newPlot->plotPane.Redraw();
00937     }
00938     else if (object == ffShow)
00939         transPanel.Show();
00940     else if (object == msgPick)
00941     {
00942         if (mainPane.selPatch[0])
00943             my_activate(examRad);
00944         else
00945             my_deactivate(examRad);
00946             
00947         if (mainPane.selPatch[0] && mainPane.selPatch[1])
00948             my_activate(examFF);
00949         else
00950             my_deactivate(examFF);
00951 
00952         matrixPane.Redraw();
00953     }
00954     else if (object == help)
00955         StartHelp();
00956     else
00957         GetFormOptions();
00958 }
00959 
00960 
00961 // --- Options panel stuff ----------------------------------------------------
00962 
00963 
00964 Void TransportPanel::Event(FL_OBJECT *object)
00965 {
00966     // nice & simple -- just hide the form if 'OK' is
00967     // clicked.
00968 
00969     if (object == dismiss)
00970         Hide();
00971     else 
00972         parent->GetFormOptions();
00973 };
00974 
00975 Void RenderPanel::Event(FL_OBJECT *object)
00976 {
00977     // nice & simple -- just hide the form if 'OK' is
00978     // clicked.
00979 
00980     if (object == dismiss)
00981         Hide();
00982     else 
00983         parent->GetFormOptions();
00984 };
00985 
00986 
00987 // --- Main -------------------------------------------------------------------
00988 
00989 
00990 Void RadForm::InitOptions(Int argc, Char **argv, RadControl &options, 
00991                           Char **scenePathP)
00992 {
00993     Int         ndm, meshRnd, meshNonLin, tri1, tri2, vers, help, noFork;  
00994     ArgForm    *arg_format;       
00995     Double      grey, clr[3];
00996     Double      meshComp = 0.1;
00997     
00998     grey = -1.0;
00999     clr[0] = 0.4; clr[1] = 0.5; clr[2] = 0.6;
01000 
01001     arg_format = arg_to_form(0,
01002         "[%S]",         scenePathP,             "Specify scene file",
01003         "-v",           ARG_FLAG(&vers),        "Print version & object info",
01004         "-h",       ARG_FLAG(&help),            "Help",
01005         "-noMatrix",    ARG_FLAG(&ndm),         "Turn off matrix display",
01006         "-bgr %F",      &grey,                  "Set background grey level",
01007         "-bgc %F %F %F", clr, clr + 1, clr + 2, "Set colour background",
01008         "-meshComp %F", &meshComp,              "Specify initial mesh complexity",
01009         "-meshRandom",  ARG_FLAG(&meshRnd),     "Vary the mesh density",
01010         "-meshNonLin",  ARG_FLAG(&meshNonLin),  "Mesh more heavily at edges",
01011         "-tri1",        ARG_FLAG(&tri1),        "Triangulate built-ins (1)",
01012         "-tri2",        ARG_FLAG(&tri2),        "Triangulate built-ins (2)",
01013         "-noFork",      ARG_FLAG(&noFork),      "Don't run in the background",
01014         0
01015         );
01016 
01017     if (arg_parse_argv(argc, argv, arg_format) < 0 || help)
01018     {
01019         String  usage;
01020         
01021         usage.Printf("Usage: %s [options], where options are as follows:", 
01022                 argv[0]);
01023 
01024         fprintf(stderr, "%s, Visualisation front end\n%s\n\n%s\n\n",
01025                 RadGetVersion().CString(),
01026                 "(c) Andrew Willmott <ajw+rad@cs.cmu.edu> 2000",
01027                 usage.CString()
01028             );
01029         arg_form_print(arg_format);
01030         cerr << endl;
01031         SceneReader::PrintSupportedFormats(cerr);
01032         exit(1);
01033     }
01034 
01035     if (vers)
01036     {
01037         cout << "Radvis version " << RadGetVersion() << endl;
01038         exit(1);
01039     }
01040 
01041 #ifndef DEBUG
01042     if (!noFork && fork())
01043         exit(0);
01044 #endif
01045 
01046     if (tri1)
01047         gQuadType = 1;
01048     else if (tri2)
01049         gQuadType = 2;
01050         
01051     options.drawMatrix = !ndm;
01052     if (meshRnd)
01053         options.mesh = mesh_random;
01054     if (meshNonLin)
01055         options.mesh = mesh_nonlin;
01056 
01057     scMRModel::SetComplexity(meshComp);
01058 
01059 
01060     if (grey >= 0.0)
01061         bgColour = cWhite * grey;
01062     else if (clr[0] >= 0.0)
01063         bgColour = Colour(clr[0], clr[1], clr[2]);
01064 }
01065 
01066 Int RadForm::Main(Int argc, Char **argv)
01067 {
01068     Char        *scenePath = 0;
01069 
01070     InitOptions(argc, argv, options, &scenePath);
01071 
01072     Show(); 
01073     Init(scenePath);
01074 
01075     fgs->Run();
01076 
01077     return(0);
01078 }
01079 
01080 main(Int argc, Char **argv)
01081 {
01082     // 'cause this calls fl_initialise, it must be created before...
01083     FormsGraphicsSystem fgs(argc, argv);
01084     // the radForm object.
01085     RadForm     radForm;
01086     radForm.fgs = &fgs;
01087 
01088     // let's boogie.
01089     return(radForm.Main(argc, argv));
01090 }

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