plvMain.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:10k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. #include <tk.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4. #ifdef WIN32
  5. #  include <io.h>
  6. #else
  7. #  include <unistd.h>
  8. #endif
  9. #include <vector.h>
  10. #include <string>
  11. #include "plvScene.h"
  12. #include "ply++.h"
  13. #include "plvInit.h"
  14. #include "plvCmds.h"
  15. #include "plvGlobals.h"
  16. #include "defines.h"
  17. #include "togl.h"
  18. #include "FileNameUtils.h"
  19. #include "plvAnalyze.h"
  20. #ifdef no_overlay_support
  21. // so I can free the saved image used to emulate overlay planes
  22. #include "plvDraw.h" 
  23. #endif
  24. vector<char*> filenames;
  25. #ifdef WIN32
  26. EXTERN int TkConsoleInit(Tcl_Interp *interp);
  27. #endif
  28. // BUGBUG - shouldn't need this here, but it helps with the compile.
  29. int isPlyFile(char *filename);
  30. static bool 
  31. isReadableFile (char* name)
  32. {
  33.   remove_trailing_slash(name);
  34.   // if it's a ply file, we want it
  35.   if (isPlyFile (name))
  36.     return true;
  37.   // if it's a set file, we want it
  38.   if ( filename_has_ending( name, ".set" ) )
  39.     return true;
  40.   // if it's an *.sd file, we want it
  41.   if ( filename_has_ending( name, ".sd" ) ||
  42.        filename_has_ending( name, ".sd.gz" ) )
  43.     return true;
  44.   // ditto for modelmaker's cta and mms format
  45.   if ( filename_has_ending(name, ".cta") || 
  46.        filename_has_ending(name, ".mms") ||
  47.        filename_has_ending(name, ".edges"))
  48.     return true;
  49.   // ditto for cyra's pts format
  50.   if ( filename_has_ending (name, ".pts") )
  51.     return true;
  52.   // also read session files
  53.   if (filename_has_ending (name, ".session"))
  54.     return true;
  55.   // and qsplat files
  56.   if ( filename_has_ending( name, ".qs" ) )
  57.     return true;
  58.   // recognize group files
  59.   if ( filename_has_ending( name, ".gp" ) ) 
  60.     return true;
  61.   
  62.   // if it's a directory containing a same-named .ply or .set file,
  63.   // we'll read that instead... so we want it
  64.   char dir[PATH_MAX];
  65.   strcpy (dir, name);
  66.   if (dir[strlen(dir) - 1] == '/')
  67.     dir[strlen(dir) - 1] = 0;
  68.   char file[PATH_MAX];
  69.   char* end = strrchr (dir, '/');
  70.   if (end != NULL)
  71.     end++;
  72.   else
  73.     end = dir;
  74.   sprintf (file, "%s/%s.set", dir, end);
  75.   if (0 == access (file, R_OK))
  76.     return true;
  77.   sprintf (file, "%s/%s.ply", dir, dir);
  78.   if (isPlyFile (file))
  79.     return true;
  80.   sprintf (file, "%s/%s.ply.gz", dir, dir);
  81.   if (isPlyFile (file))
  82.     return true;
  83.   return false;
  84. }
  85. char* find_token_end (char* begin)
  86. {
  87.   char* end = begin;
  88.   while (end != NULL && *end != 0)
  89.   {
  90.     if (*end == ' ') // space means found end.
  91.       return end;
  92.     if (*end == '\') // backslash skips over next char
  93.       ++end;
  94.     else if (*end == '"') // quote skips until matching quote
  95.       end = strchr (end + 1, '"');
  96.     else if (*end == '{') // brace skips until matching brace
  97.       end = strchr (end + 1, '}');
  98.     ++end;
  99.   }
  100.   return NULL;
  101. }
  102. /*
  103.  *----------------------------------------------------------------
  104.  *
  105.  * main --
  106.  *
  107.  * This is the main program for the application.
  108.  *
  109.  * Results:
  110.  * None: Tk_Main never returns here, so this procedure never
  111.  * returns either.
  112.  *
  113.  * Side effects:
  114.  * Whatever the application does.
  115.  *
  116.  *----------------------------------------------------------------
  117.  */
  118. int
  119. main(int argc, char **argv)
  120. {
  121.    int i;
  122. #ifdef _WIN32
  123.    // need to explicitly glob files since shell didn't
  124.    // BUGBUG: what if they use tcsh, bash, etc. which actually will?
  125.    // probably won't hurt, can't think of any reason to have escaped wildcards that
  126.    // need to come here and not get globbed.
  127.    // replacement argc, argv
  128.    vector<std::string*> argv_storage;
  129.    Tcl_Interp* interp = Tcl_CreateInterp();
  130.    for (i = 0; i < argc; i++)
  131.    {
  132.       char szGlobCmd[PATH_MAX];
  133.       sprintf (szGlobCmd, "glob "%s"", argv[i]);
  134.       if (TCL_OK == Tcl_Eval (interp, szGlobCmd))
  135.       {
  136.          char* base = interp->result;
  137.  while (base != NULL)
  138.  {
  139.             char* end = find_token_end (base);
  140.     if (end)
  141.        *end = 0;
  142.     // Tcl's glob will surround spaced-out filenames with {}
  143.     char* base_end = base + strlen (base) - 1;
  144.     if (*base == '{' && *base_end == '}')
  145.     {
  146.        base++;
  147.        *base_end = 0;
  148.     }
  149.     
  150.     argv_storage.push_back (new std::string (base));
  151.     base = end;
  152.     if (base != NULL)
  153.        ++base;
  154.  }
  155.       }
  156.       else  // glob failed -> not filename -> pass along verbatim
  157.       {
  158.          argv_storage.push_back (new std::string (argv[i]));
  159.       }
  160.    }
  161.    Tcl_DeleteInterp (interp);
  162.    // and update argc, argv
  163.    argc = argv_storage.size();
  164.    argv = new char* [ argc ];
  165.    for (i = 0; i < argc; i++)
  166.    {
  167.       argv[i] = (char*)argv_storage[i]->c_str();
  168.    }
  169. #endif
  170.    
  171.    int lastarg = argc;
  172.    // take all input files from the end of the command line back
  173.    while (isReadableFile(argv[lastarg-1])) {
  174.       lastarg--;
  175.    }
  176.    for (i = 0; i < argc - lastarg; i++) {
  177.      filenames.push_back(argv[i + lastarg]);
  178.    }
  179.    argc =  lastarg;
  180.    int iarg;
  181.    for (iarg = 1; iarg < argc; iarg++)
  182.        if (0 == strcmp(argv[iarg], "-noui")) {
  183.    g_bNoUI = true;
  184.    // if there is an argument to -noui, shift it to the beginning
  185.    if (argc > iarg+1 && argv[iarg+1][0] != '-') {
  186.        for (int jarg = iarg; jarg > 1; jarg--)
  187.    argv[jarg] = argv[jarg-1];
  188.        argv[1] = argv[iarg+1];
  189.        iarg++;
  190.    }
  191.    --argc;
  192.    for (; iarg < argc; iarg++)
  193.        argv[iarg] = argv[iarg+1];
  194.        }
  195.    for (iarg = 1; iarg < argc; iarg++)
  196.        if (0 == strcmp(argv[iarg], "-useintensity")) {
  197.    g_bNoIntensity = false;
  198.    --argc;
  199.    for (; iarg < argc; iarg++)
  200.        argv[iarg] = argv[iarg+1];
  201.        }
  202.    if (g_bNoUI)
  203.      Tcl_Main(argc, argv, Tcl_AppInit);
  204.    else
  205.      Tk_Main(argc, argv, Tcl_AppInit);
  206.    
  207. #ifdef no_overlay_support
  208.    // free the fake overaly plane
  209.    delete [] theRenderParams->savedImage;
  210. #endif
  211.    return 0;       // Needed only to prevent compiler warning.
  212. }
  213. /*
  214.  *----------------------------------------------------------------
  215.  *
  216.  * Tcl_AppInit --
  217.  *
  218.  * This procedure performs application-specific initialization.
  219.  * Most applications, especially those that incorporate additional
  220.  * packages, will have their own version of this procedure.
  221.  *
  222.  * Results:
  223.  * Returns a standard Tcl completion code, and leaves an error
  224.  * message in interp->result if an error occurs.
  225.  *
  226.  * Side effects:
  227.  * Depends on the startup script.
  228.  *
  229.  *----------------------------------------------------------------
  230.  */
  231. int
  232. Tcl_AppInit(Tcl_Interp *interp)
  233. {
  234.     /*
  235.      * Call the init procedures for included packages.  
  236.      * Each call should look like this:
  237.      *
  238.      * if (Mod_Init(interp) == TCL_ERROR) {
  239.      *     return TCL_ERROR;
  240.      * }
  241.      *
  242.      * where "Mod" is the name of the module.
  243.      */
  244. puts ("In appInit.  Modules: ");
  245.     if (Tcl_Init(interp) == TCL_ERROR)
  246.       return TCL_ERROR;
  247. puts ("Tcl...");
  248.     if (!g_bNoUI) {
  249.       if (Tk_Init(interp) == TCL_ERROR)
  250. return TCL_ERROR;
  251. puts ("Tk...");
  252. #ifdef WIN32
  253.       /*
  254.        * Set up a (GUI/Tk) console window. 
  255.        * Delete the following statement if you do not need that.
  256.        * Then it'll use a Windows (WINOLDAP) text console.
  257.        */
  258.       puts ("(This console is soon to become useless!)");
  259.       if (TkConsoleInit(interp) == TCL_ERROR) {
  260.    return TCL_ERROR;
  261.       }
  262. puts ("Console...");
  263. #endif /* WIN32 */
  264.       if (Togl_Init(interp) != TCL_OK) {
  265. fprintf(stderr, "Togl initialization failed: %sn",
  266. interp->result);
  267. return TCL_ERROR;
  268.       }
  269. puts ("Togl...");
  270.     }
  271. puts ("about to plvinit");
  272.     if (Plv_Init(interp) != TCL_OK) {
  273. fprintf(stderr, "Scanalyze initialization failed:nn%sn",
  274. interp->result);
  275. fprintf(stderr, "nThings will probably not work as expected.n");
  276.     }
  277.     Tcl_Eval(interp, "update");
  278.     // need to get z buffer minmaxes, since they're implementation-specific
  279.     // and this is known to be a safe time to call this function (rendering
  280.     // context is set up and mapped)
  281.     storeMinMaxZBufferValues();
  282.     // load any and all files specified on the command line...
  283.     // disable redraw while this is going on, though, to avoid n^2 redraws
  284.     Tcl_GlobalEval (interp, "redraw block");
  285.     // build up list of filenames, and in a separate list, build up a list
  286.     // of all group or .gp files. The .gp files are then loaded in after all 
  287.     // the files have been read, to avoid having to load files that would get 
  288.     // loaded anyway.
  289.     if (filenames.size()) {
  290.       crope filelist ("readfile");
  291.       crope grouplist ("loadgroup");
  292.       crope space (" ");
  293.       crope inbrace ("{");
  294.       crope outbrace ("}");
  295.       for (int i = 0; i < filenames.size(); i++) {
  296. // hack to determine whether the filename extension is .gp
  297. if (strncmp(filenames[i] + strlen(filenames[i]) - 3, ".gp", 3) == 0) {
  298.   grouplist += space + inbrace + filenames[i] + outbrace;
  299. } else {
  300.   filelist += space + inbrace + filenames[i] + outbrace;
  301. }
  302.       }
  303.       
  304.       if (strcmp (filelist.c_str(), "readfile") != 0) {
  305. if (TCL_OK != Tcl_Eval(interp, (char*)filelist.c_str())) {
  306.   char* err = Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY);
  307.   fprintf (stderr, "Some scans could not be loaded:n%sn", err);
  308. }
  309.       }
  310.       if (strcmp (grouplist.c_str(), "loadgroup") != 0) {
  311. Tcl_Eval(interp, (char *)grouplist.c_str());
  312. // now load in any groups
  313.        }
  314.     }
  315.     // center camera on all meshes; set home to this view
  316.     theScene->centerCamera();
  317.     theScene->setHome();
  318.     TbObj::clear_undo();
  319.     // NOW, redraw
  320.     Tcl_GlobalEval (interp, "redraw allow");
  321.     Tcl_GlobalEval (interp, "redraw 1");
  322.     // ~/.scanalyzerc is not placed in tcl_rcFileName, because then tcl
  323.     // runs it automatically without returning any error information.  So
  324.     // we explicitly source this file from plvInit(), and catch and
  325.     // display any errors that occur.
  326. #if 0
  327.     /*
  328.      * Specify a user-specific startup file to invoke if the 
  329.      * application is run interactively.  
  330.      * Typically the startup file is "~/.apprc"
  331.      * where "app" is the name of the application.  
  332.      * If this line is deleted then no user-specific 
  333.      * startup file will be run under any conditions.
  334.      */
  335.     Tcl_SetVar(interp, "tcl_rcFileName", "~/.scanalyzerc", TCL_GLOBAL_ONLY);
  336. #endif
  337.     return TCL_OK;
  338. }