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

Viewer.cc

Go to the documentation of this file.
00001 /*
00002     File:           Viewer.cc
00003 
00004     Function:       Generic viewer for gcl library
00005 
00006     Author(s):      Andrew Willmott
00007 
00008     Copyright:      (c) 1995-2000, Andrew Willmott
00009 
00010     Notes:          
00011 */
00012 
00013 #include "cl/ArgParse.h"
00014 #include "gcl/GCLApp.h"
00015 #include "gcl/ScenePane.h"
00016 #include "gcl/EPSRenderer.h"
00017 #include "gcl/MRModel.h"
00018 #include "gcl/Readers.h"
00019 #include "gcl/Writers.h"
00020 #include "cl/Timer.h"
00021 #ifdef GCL_MESA
00022 #include "gcl/MesaRenderer.h"
00023 #endif
00024 
00025 #include <unistd.h>
00026 
00027 #define GCL_WATCH_FILE
00028 
00029 #define DBG_COUT if (0) cerr
00030 
00031 
00032 // --- Viewer Pane ------------------------------------------------------------
00033 
00034 
00035 enum SDCmd 
00036 {
00037     sdNone,
00038     sdHelp,
00039     sdReload,
00040     sdNext,
00041     sdPrev,
00042     sdDumpEPS, 
00043     sdDumpPic,
00044     sdDumpHQPic,
00045     sdDumpScene,
00046     sdDumpTree,
00047     sdDumpCMB,
00048     sdQuit
00049 };
00050 
00051 class DrawScenePane : public ScenePane
00052 {
00053 public:
00054     DrawScenePane();
00055 
00056     Void            HandleKey(Char c); 
00057     Void            EndDrag(Coord end, Int modifiers); 
00058     Void            PrintSceneInfo();
00059     Void            TimeFrame();
00060 
00061     SDCmd           command;
00062     Int             hierSync;
00063 };
00064     
00065 DrawScenePane::DrawScenePane() : 
00066     ScenePane(),
00067     command(sdNone), 
00068     hierSync(false)
00069 {
00070 }
00071 
00072 Void DrawScenePane::EndDrag(Coord end, Int modifiers)
00073 {
00074     ScenePane::EndDrag(end, modifiers);
00075 
00076     if (hierSync && (modifiers & wmButton3))
00077     {
00078         command = sdDumpTree;
00079         xgs->SignalDone();
00080     }
00081 }
00082 
00083 Void DrawScenePane::HandleKey(Char c)
00084 {
00085     Bool finished = true;
00086 
00087     switch (c)
00088     {
00089     case 'h':
00090     case '?':
00091         command = sdHelp;
00092         break;
00093     case 'e':
00094         command = sdDumpEPS;
00095         break;
00096     case 'd':
00097         command = sdDumpPic;
00098         break;
00099 #ifdef GCL_MESA
00100     case 'D':
00101         command = sdDumpHQPic;
00102         break;
00103 #endif
00104     case 's':
00105         command = sdDumpScene;
00106         break;
00107     case '|':
00108         command = sdDumpTree;
00109         break;
00110     case 'B':
00111         command = sdDumpCMB;
00112         break;
00113     case 'r':
00114         command = sdReload;
00115         break;
00116     case ',':
00117     case 0x1D:
00118         command = sdPrev;
00119         break;
00120     case ' ':
00121     case '.':
00122     case 0x1C:
00123         command = sdNext;
00124         break;
00125     case 'q':
00126     case 0x1B:
00127         command = sdQuit;
00128         break;
00129     case 'i':
00130         PrintSceneInfo();
00131         finished = false;
00132         break;
00133     case 't':
00134         TimeFrame();
00135         finished = false;
00136         break;
00137     case 'c':
00138         itsCamera->PrintAvars(false);
00139         finished = false;
00140         break;
00141     case 'k':
00142         itsCamera->PrintAvars(true);
00143         finished = false;
00144         break;
00145     case 'R':
00146         // print radiance camera params
00147         {
00148             ItsCamera()->GetViewDirParams();
00149 
00150             Point lookFrom = ItsCamera()->position;
00151             Point lookDir = ItsCamera()->viewDir;
00152             Point lookUp = ItsCamera()->up;
00153 
00154             printf("rview -vtv -vp %g %g %g -vd %g %g %g -vu %g %g %g -vh %g -vv %g -vo 0 -va 0 -vs 0 -vl 0\n",
00155                 lookFrom[0], lookFrom[1], lookFrom[2], 
00156                 lookDir[0], lookDir[1], lookDir[2],
00157                 lookUp[0], lookUp[1], lookUp[2],
00158                 ItsCamera()->fov * 2.0, ItsCamera()->fov * 2.0
00159             );
00160         }
00161         finished = false;
00162         break;
00163                                     
00164     default:
00165         ScenePane::HandleKey(c);
00166         finished = false;
00167     }
00168 
00169     if (finished)
00170         xgs->SignalDone();
00171 }
00172 
00173 Void DrawScenePane::PrintSceneInfo()
00174 {
00175     Int         i;
00176     FindDecInfo decInfo;
00177     
00178     ItsScene()->Decimate(decInfo, DecTris);
00179     
00180     cout << "Scene info:" << endl;
00181     cout << "  " << decInfo.numTris << " triangles" << endl;
00182     cout << "  " << decInfo.numPolys << " polygons" << endl;
00183 
00184     for (i = 0; i < models.NumModels(); i++)
00185     {
00186         if (models.Model(i)->clusters.NumItems() > 0)
00187         {
00188             cout << "  Model " << i << " has " << models.Model(i)->currentClusters
00189                  << " clusters out of " << models.Model(i)->faces.NumItems()
00190                  << ", and " << models.Model(i)->rootClusters.NumItems() << " root clusters" << endl;
00191         }
00192         if (models.Model(i)->vertices.NumItems() > 0)
00193             cout << "  Model " << i << " has " << models.Model(i)->currentFaces
00194                  << " faces out of " << models.Model(i)->faces.NumItems() << endl;
00195     }
00196 }
00197 
00198 Void DrawScenePane::TimeFrame()
00199 {
00200     ProgramTimer    timer;
00201     Float           time;
00202     Int             i, count = 0;
00203     
00204     cout << "timing redraw rate" << endl;
00205     timer.StartTimer();
00206     cout << timer.GetTimer() << endl;
00207 
00208     while (timer.GetTimer() < 10.0)
00209     {
00210         Clear().Draw(ItsScene()).Show();
00211         count++;
00212     }
00213 
00214     cout << timer.GetTimer() << endl;
00215     time = timer.GetTimer();
00216 
00217     timer.StartTimer();
00218     cout << timer.GetTimer() << endl;
00219     for (i = 0; i < count; i++)
00220         ;
00221     cout << timer.GetTimer() << endl;
00222     time -= timer.GetTimer();
00223     time /= count;
00224     
00225     cout << "frame drawing time: " << time << " seconds" << endl;
00226     cout << "frames per second: " << 1.0 / time  << endl;
00227 }
00228 
00229 
00230 // --- ViewerApp --------------------------------------------------------------
00231 
00233 
00234 class ViewerApp : public GCLApp
00235 {
00236 public:
00237 
00238     Void            PrintKeys();
00239     Void            SetOptions(Int argc, Char **argv);
00240     Int             Run();
00241     Void            DrawScene();
00242     Void            SetupModels(scScenePtr scene);
00243     
00244 // options
00245     Char            *output;
00246     Int             window;
00247     Int             ord;
00248     Int             noFork;
00249     Double          clusComp;
00250     Double          meshComp;
00251     Int             noLight;
00252     Int             hierSync;
00253     
00254 // fields
00255     XGraphicsSystem *xgs;
00256     DrawScenePane   *displayPane;
00257 };
00258 
00259 Void ViewerApp::PrintKeys()
00260 {
00261     cout << "Viewer control:" << endl
00262          << "  mouse 1 -- rotation" << endl
00263          << "  shift+mouse 1 -- zoom" << endl
00264          << "  mouse 2 -- translate x & y" << endl
00265          << "  shift+mouse 2 -- translate z" << endl
00266          << "  mouse 3 -- adjust scene complexity" << endl
00267          << endl
00268          << "  . space - move on to next scene file" << endl
00269          << "  , - move back to previous scene file" << endl
00270          << endl
00271          << "  w - toggle wireframe" << endl
00272          << "  0 - turn off lighting" << endl
00273          << "  1 - turn on lighting" << endl
00274          << "  ) - single-sided polygons" << endl
00275          << "  ! - double-sided polygons" << endl
00276          << endl
00277          << "  G - toggle grid" << endl
00278          << "  A - toggle axes" << endl
00279          << "  S - simplest model" << endl
00280          << "  C - complex model" << endl
00281          << "  F - toggle display of faces" << endl
00282          << "  V - toggle visualisation of vertices/face clusters" << endl
00283          << "  X - toggle colouring of face clusters" << endl
00284          << endl
00285          << "  d - save image" << endl
00286          << "  D - save super-sampled image" << endl
00287          << "  s - save scene file" << endl
00288          << "  e - save eps file" << endl
00289          << "  i - print scene information" << endl
00290          << "  c - save camera parameters" << endl
00291          << "  q esc - quit" << endl
00292          << endl;
00293 }
00294 
00295 Void ViewerApp::SetOptions(Int argc, Char **argv)
00296 {
00297     ArgForm     *arg_format, *argForm2;
00298     Double      grey, clr[3], defClr[3];
00299     Int         size;
00300     Int         formats;
00301     Int         keys;
00302     Int         avgClus;
00303 
00304     size = 400;
00305     xsize = -1;
00306     ysize = -1;
00307     output = 0;
00308     grey = 0.5;
00309     clr[0] = -1;
00310     defClr[0] = -1;
00311     clusComp = -1.0;
00312     meshComp = -1.0;
00313     
00314     arg_format = arg_to_form(0,
00315         "", 
00316             "Usage: slview file1 file2 ... [options]",
00317         "", ARG_SUBR(GetFileArgs), 
00318             "",
00319         "-o %S", &output,
00320             "Set output file",
00321         "-bgr %F", &grey,
00322             "Set background grey level",
00323         "-bgc %F %F %F", clr, clr + 1, clr + 2, 
00324             "Set colour background",
00325         "-defClr %F %F %F", defClr, defClr + 1, defClr + 2, 
00326             "Set default model colour",
00327         "-noFork", ARG_FLAG(&noFork),
00328             "Don't fork into background.",
00329         "-avgClus", ARG_FLAG(&avgClus),
00330             "Colour parent clusters according to average of children.",
00331         "-set", ARG_SUBR(GetAvarArgs),
00332             "Set avar, e.g. -set light 0.5 height 0.2",
00333         "-clusComp %F", &clusComp,
00334             "Set face cluster complexity",
00335         "-meshComp %F", &meshComp,
00336             "Set model complexity",
00337         "-noLight", ARG_FLAG(&noLight),
00338             "Don't use headlight",
00339         "-hierSync", ARG_FLAG(&hierSync),
00340             "Keep hierarchy file in sync",
00341         "-controls", ARG_FLAG(&keys),
00342             "List keyboard and mouse controls",
00343         "-formats", ARG_FLAG(&formats), 
00344             "List supported file formats",
00345 
00346         // Output options       
00347         "-size %d", &size,
00348             "Set window size",
00349         "-xysize %d %d", &xsize, &ysize,
00350             "Set output size",
00351         0);
00352 
00353     argForm2 = arg_to_form(0,
00354             "-noScale", ARG_FLAG(&noScale),
00355             "Don't rescale scene.",
00356             "-zup", ARG_FLAG(&zUp),
00357                 "z axis is up (default is y axis.)",
00358             "-zdown", ARG_FLAG(&zDown),
00359                 "z axis is down",
00360         0);
00361     
00362     arg_form_append(arg_format, argForm2);
00363 
00364     if (argc == 1)
00365     {
00366         arg_form_print(arg_format);
00367         cout << endl;
00368         exit(0);
00369     }
00370 
00371     if (arg_parse_argv(argc, argv, arg_format) < 0)
00372         exit(1);
00373 
00374     if (formats)
00375     {
00376         SceneReader::PrintSupportedFormats(cout);
00377         Image::PrintSupportedFormats(cout);
00378         exit(0);
00379     }
00380 
00381     if (keys)
00382     {
00383         PrintKeys();
00384         exit(0);
00385     }       
00386 
00387     if (!avgClus)
00388         MRModel::sAvgClusColours = false;
00389     
00390     if (clr[0] < 0)
00391         bgColour = cWhite * grey;
00392     else
00393         bgColour = Colour(clr[0], clr[1], clr[2]);
00394 
00395     if (defClr[0] >= 0)
00396         scPrimitive::sDefaultColour = Colour(defClr[0], defClr[1], defClr[2]);
00397 
00398     if (xsize < 0)
00399         xsize = size;
00400     if (ysize < 0)
00401         ysize = size;
00402 }
00403 
00404 Int ViewerApp::Run()
00405 {
00406     if (numFiles < 1)
00407         return(1);
00408         
00409     xgs = new XGraphicsSystem;
00410     slInit();
00411 
00412 #ifndef DEBUG
00413     if (!noFork && fork())
00414         return(0);
00415 #endif
00416 
00417     DrawScene();
00418 
00419     return(0);
00420 }
00421 
00422 Void ViewerApp::SetupModels(scScenePtr scene)
00423 {
00424     Int     i;
00425 
00426     if (meshComp >= 0.0)
00427         scMRModel::SetComplexity(meshComp); 
00428     else if (clusComp >= 0.0)
00429     {
00430         MRModelsFinder  models;
00431 
00432         scene->ApplyAction(models);
00433 
00434         scMRModel::SetComplexity(clusComp);
00435 
00436         for (i = 0; i < models.NumModels(); i++)
00437         {
00438             models.Model(i)->showFaces = false;
00439             models.Model(i)->showMeta = true;
00440             models.Model(i)->AdaptComplexity(clusComp);
00441         }
00442     }
00443 }
00444 
00445 Void ViewerApp::DrawScene()
00446 {
00447     Int                     i, j;
00448     RGBAImage               image;
00449     FileName                sceneFile, outFile, saveFile;
00450     ofstream                fout;
00451     Bool                    window = false, reload;
00452     
00453     scene = 0;
00454     displayPane = new DrawScenePane();
00455     displayPane->SetBgColour(bgColour);
00456     displayPane->hierSync = hierSync;
00457     itsScenePane = displayPane;
00458         
00459     i = 0;
00460     reload = true;
00461     
00462     while (displayPane->command != sdQuit)
00463     {
00464         if (reload)
00465         {
00466             delete scene;
00467             sceneFile.SetPath(files[i]);
00468 
00469             ReadScene(sceneFile);
00470             if (!scene && !window)
00471                 exit(1);
00472             
00473             if (!itsCamera)
00474             {
00475                 itsCamera = (scCamera*) scene->FindFirst(aCamera);
00476                 if (!itsCamera)
00477                     itsCamera = new scCamera;
00478                 scene->Set(itsCamera);
00479             }
00480 
00481             SetAvars(scene);
00482             SetupModels(scene);
00483 
00484             if (output)
00485                 outFile.SetPath(output);
00486             else
00487             {
00488                 outFile = sceneFile;
00489                 outFile.SetDir(".");
00490                 outFile.SetExtension("");
00491             }
00492             sceneFile.AddCompExt(); // add the compression extension so we
00493                                     // can watch the file
00494         }
00495         
00496         // we do this here to avoid creating a window until we know we've
00497         // successfully read the file.
00498         if (!window)
00499         {
00500             xgs->CreateWindow(displayPane, files[0],
00501                             xsize, ysize);
00502             displayPane->SetHeadlight(!noLight);
00503             window = true;
00504         }
00505 
00506         if (reload)
00507         {           
00508             displayPane->SetScene(scene);
00509             displayPane->SetTitle(files[i]);
00510             reload = false;
00511         }
00512         
00513         // spin while the user manipulates the scene
00514 
00515 #ifndef GCL_WATCH_FILE
00516         xgs->Run();
00517 #else
00518         Long            timeStamp;
00519 
00520         displayPane->command = sdNone;
00521         timeStamp = sceneFile.GetTimeStamp();
00522 
00523         while (true)
00524         {
00525             xgs->RunFor(1.0);   // check once a second
00526             if (displayPane->command != sdNone)
00527                 break;
00528 
00529             if (sceneFile.GetTimeStamp() > timeStamp)
00530             {
00531                 displayPane->command = sdReload;
00532                 break;
00533             }
00534         }
00535 #endif
00536 
00537         switch (displayPane->command)
00538         {
00539         case sdQuit:
00540             break;
00541         case sdHelp:
00542             PrintKeys();
00543             break;
00544         case sdReload:
00545             reload = true;
00546             break;
00547         case sdPrev:
00548             if (i > 0)
00549                 i--;
00550             else
00551                 i = numFiles - 1;
00552             reload = true;
00553             break;
00554         case sdNext:
00555             i++;
00556             if (i == numFiles)
00557                 i = 0;
00558             reload = true;
00559             break;
00560         case sdDumpPic:
00561             saveFile = outFile;
00562             if (saveFile.GetExtension() == "")
00563                 saveFile.SetExtension("tif");
00564             saveFile.MakeUnique();
00565             cout << "*** saving image to " << saveFile.GetPath() << endl;
00566             displayPane->GetImage(image);
00567             image.Save(saveFile);
00568             break;
00569 #ifdef GCL_MESA
00570         case sdDumpHQPic:
00571             {
00572                 MesaRenderer    mr;
00573                 RGBAImage       hqImage;
00574 
00575                 saveFile = outFile;
00576                 if (saveFile.GetExtension() == "")
00577                     saveFile.SetExtension("tif");
00578                 saveFile.MakeUnique();
00579                 cout << "*** saving high quality image to " << saveFile.GetPath() << endl;
00580                 
00581                 image.SetSize(2 * xsize, 2 * ysize);
00582                 hqImage.SetSize(xsize, ysize);
00583                 mr.Init(image);
00584                 mr.SetHeadlight(!noLight);
00585                 mr.SetBgColour(bgColour);
00586                 mr.Clear().Draw(displayPane->ItsScene()).Show();
00587                 image.DownSample(hqImage);
00588                 hqImage.Save(saveFile);
00589             }
00590             break;
00591 #endif
00592         case sdDumpScene:
00593             saveFile = outFile;
00594             if (saveFile.GetExtension() == "")
00595                 saveFile.SetExtension("sl");
00596             saveFile.MakeUnique();
00597             cout << "*** saving scene to " << saveFile.GetPath() << endl;
00598             SceneWriter().Save(displayPane->ItsScene(), saveFile);
00599             break;
00600         case sdDumpTree:
00601             saveFile = outFile;
00602             saveFile.SetExtension("hier");
00603 //          saveFile.MakeUnique();
00604             cout << "*** saving .hier file to " << saveFile.GetPath() << endl;
00605 
00606             if (displayPane->models.NumModels() > 0)
00607                 displayPane->models.Model(0)->DumpFCH(saveFile.GetPath());
00608             break;
00609         case sdDumpCMB:
00610             if (displayPane->models.NumModels() > 0)
00611                 displayPane->models.Model(0)->WriteBinary();
00612             break;
00613         case sdDumpEPS:
00614             EPSRenderer     eps;
00615 
00616             saveFile = outFile;
00617             saveFile.SetExtension("eps");
00618             saveFile.MakeUnique();
00619             cout << "*** saving EPS file to " << saveFile.GetPath() << endl;
00620             eps.itsPlot.level2 = true;
00621             eps.Attach(saveFile.GetPath());
00622             eps.Clear().Draw(displayPane->ItsScene()).Show();
00623             break;
00624         }
00625     }
00626 }
00627 
00628 // ----------------------------------------------------------------------------
00629 
00630 main(Int argc, Char **argv)
00631 {
00632     ViewerApp   app;
00633     
00634     app.SetOptions(argc, argv);
00635 
00636     return(app.Run());
00637 }

Generated at Sat Aug 5 00:17:05 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000