OpenFlipper.cc 10.5 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  OpenFlipper is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16
17
18
19
//  OpenFlipper is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================




// Mainwindow

#include "OpenFlipper/Core/Core.hh"

// Qt
#include <qapplication.h>
#include <qgl.h>

// stdc++
#include <iostream>
#include <fstream>
#include <csignal>
#include <cstdlib>

#include "OpenFlipper/common/GlobalOptions.hh"

#include <OpenFlipper/SimpleOpt/SimpleOpt.h>

Mike Kremer's avatar
Mike Kremer committed
53
#if ( defined(WIN32) || defined(ARCH_DARWIN) )
Mike Kremer's avatar
Mike Kremer committed
54
55
56
57
  #define NO_EXECINFO
#endif

#ifndef NO_EXECINFO
58
#include <execinfo.h>
Jan Möbius's avatar
 
Jan Möbius committed
59
60
61
62
63
64
#endif

#ifdef USE_OPENMP
#include <omp.h>
#endif

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// #ifndef WIN32
//
// #include <sys/resource.h>
//
// void getSystemInfo() {
//
//   struct rusage resource_usage;
//   if (getrusage(RUSAGE_SELF, &resource_usage))
//   {
//     //error - call to getrusage failed - handle it
//     std::cerr << "Unable to get process information" << std::endl;
//   }
//   else
//   {
//     std::cerr << "Got process information" << std::endl;
//     std::cerr << "Maximum resident size   : " << resource_usage.ru_maxrss << std::endl;
//     std::cerr << "Shared Memory size      : " << resource_usage.ru_ixrss << std::endl;
//     std::cerr << "Unshared Data size      : " << resource_usage.ru_idrss << std::endl;
//     std::cerr << "Unshared Stack size     : " << resource_usage.ru_isrss << std::endl;
//     std::cerr << "Page faults             : " << resource_usage.ru_majflt << std::endl;
//     std::cerr << "Block input operations  : " << resource_usage.ru_inblock << std::endl;
//     std::cerr << "Block output operations : " << resource_usage.ru_oublock << std::endl;
//
//
//     //call successful
//     //get values for resident set size (ru_idrss)
//     //swap space is probably not accounted for but thats all what this
//     //call gives you...

//     struct rusage {
//         struct timeval ru_utime; /* user time used */
//         struct timeval ru_stime; /* system time used */
//         long   ru_minflt;        /* page reclaims */
//         long   ru_nswap;         /* swaps */
//         long   ru_msgsnd;        /* messages sent */
//         long   ru_msgrcv;        /* messages received */
//         long   ru_nsignals;      /* signals received */
//         long   ru_nvcsw;         /* voluntary context switches */
//         long   ru_nivcsw;        /* involuntary context switches */
//     };


//   }

// }

// #endif



Jan Möbius's avatar
 
Jan Möbius committed
115
enum {OPT_HELP , OPT_STEREO, OPT_BATCH ,OPT_CONSOLE_LOG , OPT_DEBUGGING, OPT_FULLSCREEN,
116
      OPT_HIDDDEN_LOGGER , OPT_NOSPLASH ,OPT_HIDDDEN_TOOLBOX , OPT_LOAD_POLYMESHES,
Jan Möbius's avatar
 
Jan Möbius committed
117
118
119
      OPT_REMOTE};

CSimpleOpt::SOption g_rgOptions[] = {
120
121
122
123
124
125
126
127
128
129
130
131
132
    { OPT_DEBUGGING        , (char*) "--debug"          , SO_NONE    },
    { OPT_HELP             , (char*) "-?"               , SO_NONE    },
    { OPT_HELP             , (char*) "--help"           , SO_NONE    },
    { OPT_HELP             , (char*) "-h"               , SO_NONE    },
    { OPT_STEREO           , (char*) "--enable-stereo"  , SO_NONE    },
    { OPT_BATCH            , (char*) "-b"               , SO_NONE    },
    { OPT_CONSOLE_LOG      , (char*) "-c"               , SO_NONE    },
    { OPT_CONSOLE_LOG      , (char*) "--log-to-console" , SO_NONE    },
    { OPT_FULLSCREEN       , (char*) "-f"               , SO_NONE    },
    { OPT_HIDDDEN_LOGGER   , (char*) "-l"               , SO_NONE    },
    { OPT_NOSPLASH         , (char*) "--no-splash"      , SO_NONE    },
    { OPT_HIDDDEN_TOOLBOX  , (char*) "-t"               , SO_NONE    },
    { OPT_LOAD_POLYMESHES  , (char*) "-p"               , SO_NONE    },
Dirk Wilden's avatar
Dirk Wilden committed
133
//     { OPT_DARWINPHANTOM    , (char*) "-psn_"            , SO_NONE    },
134
    { OPT_REMOTE           , (char*) "--remote-control" , SO_NONE    },
Jan Möbius's avatar
 
Jan Möbius committed
135
136
137
138
139
140
141
    SO_END_OF_OPTIONS                       // END
};

void showHelp() {
  std::cerr << "OpenFlipper [Options] <filenames> " << std::endl << std::endl;;
  std::cerr << "Possible Options : " << std::endl;
  std::cerr << std::endl;
142
143
144
145
146
147
148
149
150
151
152
153

  std::cerr << "Load/Save Options:" << std::endl;
  std::cerr << " -p \t: Open files as PolyMeshes" << std::endl;
  std::cerr << std::endl;

  std::cerr << "Gui Options:" << std::endl;
  std::cerr << " -f \t\t: Start Fullscreen" << std::endl;
  std::cerr << " -l \t\t: Start with hidden logger" << std::endl;
  std::cerr << " -t \t\t: Start with hidden Toolbox" << std::endl;
  std::cerr << " --no-splash \t: Disable splash screen" << std::endl;

  std::cerr << " --enable-stereo \t: Enable Stereo Mode" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
154
  std::cerr << std::endl;
155
156
157

  std::cerr << "Log options:" << std::endl;
  std::cerr << " --log-to-console ( -c ) \t: Write logger window contents to console" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
158
  std::cerr << std::endl;
159
160
161
162
163

  std::cerr << "Other options:" << std::endl;
  std::cerr << " -b \t: Batch mode, you have to provide a script for execution" << std::endl;
  std::cerr << " --remote-control \t: Batch mode accepting remote connections" << std::endl;

Jan Möbius's avatar
 
Jan Möbius committed
164
  std::cerr << std::endl;
165
166
167


  std::cerr << " -h \t: This help" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
168
169
170
}


Mike Kremer's avatar
Mike Kremer committed
171
#ifndef NO_EXECINFO
Jan Möbius's avatar
 
Jan Möbius committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
void backtrace()
{
  void *addresses[10];
  char **strings;

  int size = backtrace(addresses, 10);
  strings = backtrace_symbols(addresses, size);
  std::cerr << "Stack frames: " << size << std::endl;
  for(int i = 0; i < size; i++)
    std::cerr << i << ": " << strings[i] << std::endl;
  free(strings);
}
#endif

void segfaultHandling (int) {
187

Jan Möbius's avatar
 
Jan Möbius committed
188
189
190
191
192
193
194
195
196
197
198
  // prevent infinite recursion if segfaultHandling() causes another segfault
  std::signal(SIGSEGV, SIG_DFL);


  std::cerr << "\n" << std::endl;
  std::cerr << "\n" << std::endl;
  std::cerr << "\33[31m" << "=====================================================" << std::endl;
  std::cerr << "\33[31m" << "OpenFlipper or one of its plugins caused a Segfault." << std::endl;
  std::cerr << "\33[31m" << "This should not happen,... Sorry :-(" << std::endl;
  std::cerr << "\33[31m" << "=====================================================" << std::endl;
  std::cerr << "\n" << std::endl;
Mike Kremer's avatar
Mike Kremer committed
199
#ifndef NO_EXECINFO
Jan Möbius's avatar
 
Jan Möbius committed
200
201
  std::cerr << "\33[0m"  << "Trying a backtrace to show what happened last: " << std::endl;
  backtrace();
202

Jan Möbius's avatar
 
Jan Möbius committed
203
204
  std::cerr << "\n" << std::endl;
  std::cerr << "Backtrace completed, trying to abort now ..." << std::endl;
205

Jan Möbius's avatar
 
Jan Möbius committed
206
#endif
207

Jan Möbius's avatar
 
Jan Möbius committed
208
209
210
  std::abort();
}

Dirk Wilden's avatar
Dirk Wilden committed
211
212
bool openPolyMeshes = false;
bool remoteControl  = false;
213

Dirk Wilden's avatar
Dirk Wilden committed
214
bool parseCommandLineOptions(CSimpleOpt& args){
215

Jan Möbius's avatar
 
Jan Möbius committed
216
217
  // while there are arguments left to process
  while (args.Next()) {
Dirk Wilden's avatar
Dirk Wilden committed
218
219
220
221
222
223
224

    //ignore Darwin -psn flags
    std::string argStr( args.OptionText() );

    if ( argStr.find("-psn") != std::string::npos)
        continue;

Jan Möbius's avatar
 
Jan Möbius committed
225
    if (args.LastError() == SO_SUCCESS) {
Dirk Wilden's avatar
Dirk Wilden committed
226

Jan Möbius's avatar
 
Jan Möbius committed
227
228
229
230
231
232
233
234
235
      switch (args.OptionId() ) {
        case OPT_BATCH:
          OpenFlipper::Options::nogui(true);
        break;
        case OPT_CONSOLE_LOG:
          OpenFlipper::Options::logToConsole(true);
          break;
        case OPT_DEBUGGING:
          OpenFlipper::Options::debug(true);
236
          break;
Jan Möbius's avatar
 
Jan Möbius committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
        case OPT_STEREO:
            OpenFlipper::Options::stereo(true);
            break;
        case OPT_HIDDDEN_TOOLBOX:
            OpenFlipper::Options::hideToolbox(true);
            break;
        case OPT_HIDDDEN_LOGGER:
            OpenFlipper::Options::hideLogger(true);
            break;
        case OPT_FULLSCREEN:
            OpenFlipper::Options::fullScreen(true);
            break;
        case OPT_LOAD_POLYMESHES:
            openPolyMeshes = true;
            break;
        case OPT_NOSPLASH:
            OpenFlipper::Options::splash(false);
            break;
        case OPT_REMOTE:
            remoteControl = true;
            break;
        case OPT_HELP:
          showHelp();
          return 0;
      }
    } else {
      std::cerr << "Invalid argument: " << args.OptionText() << std::endl;
      showHelp();
Dirk Wilden's avatar
Dirk Wilden committed
265
      return false;
Jan Möbius's avatar
 
Jan Möbius committed
266
267
    }
  }
Dirk Wilden's avatar
Dirk Wilden committed
268
269
270
271
272
273
274
275
  return true;
}

int main(int argc, char **argv)
{
  OpenFlipper::Options::argc(&argc);
  OpenFlipper::Options::argv(&argv);

Dirk Wilden's avatar
Dirk Wilden committed
276
277
278
279
280
  //print arguments
  for (int i=0; i < argc; i++)
    std::cerr << argv[i] << " ";
  std::cerr << std::endl;

Dirk Wilden's avatar
Dirk Wilden committed
281
282
283
284
285
286
287
288
289
  CSimpleOpt args(argc, argv, g_rgOptions);

// Only Install signal handler if not running in debug version, otherwise gdb will get confused
// #ifndef DEBUG
  // Set a handler for segfaults
  std::signal(SIGSEGV, segfaultHandling);
// #endif

  OpenFlipper::Options::windowTitle("OpenFlipper v" + OpenFlipper::Options::coreVersion());
290

Jan Möbius's avatar
 
Jan Möbius committed
291
  if ( !OpenFlipper::Options::nogui() ) {
292

Jan Möbius's avatar
 
Jan Möbius committed
293
294
295
    // OpenGL check
    QApplication::setColorSpec( QApplication::CustomColor );
    QApplication app(argc,argv);
296

Jan Möbius's avatar
 
Jan Möbius committed
297
298
299
300
    if ( !QGLFormat::hasOpenGL() ) {
      std::cerr << "This system has no OpenGL support.\n";
      return -1;
    }
301

Jan Möbius's avatar
 
Jan Möbius committed
302
    glutInit(&argc,argv);
303

Jan Möbius's avatar
 
Jan Möbius committed
304
305
    // create core ( this also reads the ini files )
    Core * w = new Core( );
306

Dirk Wilden's avatar
Dirk Wilden committed
307
308
309
    if ( !parseCommandLineOptions(args) )
      return 1;

Jan Möbius's avatar
 
Jan Möbius committed
310
311
    // After setting all Options from command line, build the real gui
    w->init();
312

313
314
315
316
317
318
319
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
      /* Problem: glewInit failed, something is seriously wrong. */
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    }

320
    for ( int i = 0 ; i < args.FileCount(); ++i )
Jan Möbius's avatar
 
Jan Möbius committed
321
      w->commandLineOpen(args.File(i), openPolyMeshes);
322

Jan Möbius's avatar
 
Jan Möbius committed
323
    return app.exec();
324

Jan Möbius's avatar
 
Jan Möbius committed
325
  } else {
326

Jan Möbius's avatar
 
Jan Möbius committed
327
    QCoreApplication app(argc,argv);
328

Jan Möbius's avatar
 
Jan Möbius committed
329
330
    // create widget ( this also reads the ini files )
    Core * w = new Core( );
331

Dirk Wilden's avatar
Dirk Wilden committed
332
333
334
    if ( !parseCommandLineOptions(args) )
      return 1;

Jan Möbius's avatar
 
Jan Möbius committed
335
336
    // After setting all Options from command line, build the real gui
    w->init();
337
338
339
340

    for ( int i = 0 ; i < args.FileCount(); ++i )
      w->commandLineScript(args.File(i));

Jan Möbius's avatar
 
Jan Möbius committed
341
342
343
344
345
346
    if ( remoteControl)
      return app.exec();
  }

  return 0;
}