OpenFlipper.cc 19.2 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
40
*                                                                            *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
41

42

Jan Möbius's avatar
 
Jan Möbius committed
43
44
45
46
47
48



// Mainwindow

#include "OpenFlipper/Core/Core.hh"
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
49
#include "common/glew_wrappers.hh"
50
#include "OpenFlipper/BasePlugin/PluginFunctionsCore.hh"
Jan Möbius's avatar
 
Jan Möbius committed
51
52
53
54
55
56

// Qt
#include <qgl.h>

// stdc++
#include <csignal>
57
#include <regex>
58
59

#include <QCommandLineParser>
Jan Möbius's avatar
 
Jan Möbius committed
60

Matthias Möller's avatar
Matthias Möller committed
61
#if ( defined(WIN32))
Mike Kremer's avatar
Mike Kremer committed
62
63
64
65
  #define NO_EXECINFO
#endif

#ifndef NO_EXECINFO
66
#include <execinfo.h>
Jan Möbius's avatar
 
Jan Möbius committed
67
68
#endif

69
70
71
72
#ifdef PYTHON_ENABLED
  #include <PythonInterpreter/PythonInterpreter.hh>
#endif

Jan Möbius's avatar
 
Jan Möbius committed
73
74
75
#ifdef USE_OPENMP
#endif

76
#ifdef WIN32
77
  #include <Windows/windows-startup.hh>
78
79
#endif

80

81

82
83
84
85
86
87
88

/* ==========================================================
 *
 * Linux function printing a full stack trace to the console
 *
 * ==========================================================*/
#ifndef NO_EXECINFO
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

#if defined(__GLIBCXX__) || defined(__GLIBCPP__)
// GCC: implement demangling using cxxabi
#include <cxxabi.h>
std::string demangle(const std::string& _symbol)
{
    int status;
    char* demangled = abi::__cxa_demangle(_symbol.c_str(), nullptr, nullptr, &status);
    if (demangled) {
        std::string result{demangled};
        free(demangled);
        if (status == 0) {
            return result;
        }
        else {
            return _symbol;
        }
    }
    else {
        return _symbol;
    }
}
#else
// other compiler environment: no demangling
std::string demangle(const std::string& _symbol)
114
{
115
116
117
    return _symbol;
}
#endif
118

119
120
121
122
void backtrace()
{
    void *addresses[20];
    char **strings;
Jan Möbius's avatar
Jan Möbius committed
123

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    int size = backtrace(addresses, 20);
    strings = backtrace_symbols(addresses, size);
    std::cerr << "Stack frames: " << size << std::endl;
    // line format:
    // <path>(<mangled_name>+<offset>) [<address>]
    std::regex line_format{R"(^\s*(.+)\((([^()]+)?\+(0x[0-9a-f]+))?\)\s+\[(0x[0-9a-f]+)\]\s*$)"};
    for(int i = 0; i < size; i++) {
        std::string line{strings[i]};
        std::smatch match;
        std::regex_match(line, match, line_format);
        if (!match.empty()) {
            auto file_name = match[1].str();
            auto symbol = demangle(match[3].str());
            auto offset = match[4].str();
            auto address = match[5].str();
            std::cerr << i << ":";
            if (!file_name.empty()) std::cerr << " " << file_name << " ::";
            if (!symbol.empty()) std::cerr << " " << symbol;
            if (!offset.empty()) std::cerr << " (+" << offset << ")";
            if (!address.empty()) std::cerr << " [" << address << "]";
            std::cerr << std::endl;
        }
    }
    free(strings);
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
}
#endif

/* ==========================================================
 *
 * General segfault handler. This function is called if OpenFlipper
 * crashes
 *
 * ==========================================================*/
void segfaultHandling (int) {

  // 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;

  // Linux Handler
#ifndef NO_EXECINFO
  std::cerr << "\33[0m"  << "Trying a backtrace to show what happened last: " << std::endl;
  backtrace();

  std::cerr << "\n" << std::endl;
  std::cerr << "Backtrace completed, trying to abort now ..." << std::endl;
#endif

  // Windows handler via StackWalker
#ifdef WIN32
  StackWalkerToConsole sw;
  sw.ShowCallstack();
#endif


Jan Möbius's avatar
Jan Möbius committed
187
188
189
190
191
192
193
194
  std::cerr << "Trying to get additional information (This might fail if the memory is corrupted)." << std::endl;

  if (OpenFlipper::Options::gui()) {
    for ( unsigned int i = 0 ; i <  4 ; ++i) {
      std::cerr << "DrawMode Viewer "<<  i << " " << PluginFunctions::drawMode(i).description() << std::endl;
    }
  }

195
196
  std::abort();
}
197

198
199
200
201
202
203
enum CommandLineParseResult
{
    CommandLineOk,
    CommandLineError,
    CommandLineVersionRequested,
    CommandLineHelpRequested
Jan Möbius's avatar
 
Jan Möbius committed
204
205
};

206

207
208
bool openPolyMeshes = false;
bool remoteControl  = false;
209

210
211
// Parse all options
CommandLineParseResult parseCommandLine(QCommandLineParser &parser, QString *errorMessage) {
212

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  #ifndef WIN32
  #ifndef __APPLE__
    //workaround for bug with stereo mode on Qt5.7.0 and Qt5.7.1 on Linux
    int QtVersionMajor, QtVersionMinor, QtVersionPatch;
    if(sscanf(qVersion(),"%1d.%1d.%1d",&QtVersionMajor, &QtVersionMinor, &QtVersionPatch) == 3)
    {
      if(QtVersionMajor == 5 && QtVersionMinor >= 7)
      {
        if(QtVersionPatch < 2)
        {
          std::cerr << "The used Qt Version does not support stereo mode. Disabling stereo mode." << std::endl;
          OpenFlipper::Options::stereo(false);
        }
        else
          std::cerr << "Stereo Mode has not been tested for the used Qt Version." << std::endl;
      }
    }
  #endif
  #endif


 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);

236

237
238
 QCommandLineOption debugOption(QStringList() << "d" << "debug",QCoreApplication::translate("main", "Enable debugging mode"));
 parser.addOption(debugOption);
239

240
241
 QCommandLineOption stereoOption("disable-stereo",QCoreApplication::translate("main", "Disable stereo mode"));
 parser.addOption(stereoOption);
Jan Möbius's avatar
 
Jan Möbius committed
242

243
244
 QCommandLineOption batchOption(QStringList() << "b" << "batch",QCoreApplication::translate("main", "Batch mode, you have to provide a script for execution"));
 parser.addOption(batchOption);
Jan Möbius's avatar
 
Jan Möbius committed
245

246
247
 QCommandLineOption logConsoleOption(QStringList() << "c" << "log-to-console",QCoreApplication::translate("main", "Write logger window contents to console"));
 parser.addOption(logConsoleOption);
248

249
250
 QCommandLineOption remoteControlOption("remote-control",QCoreApplication::translate("main", "Batch mode accepting remote connections"));
 parser.addOption(remoteControlOption);
251

252
 QCommandLineOption fulscreenOption(QStringList() << "f" << "fullscreen",QCoreApplication::translate("main", "Start in fullscreen mode"));
253
 parser.addOption(fulscreenOption);
254

255
256
 QCommandLineOption hideLoggerOption(QStringList() << "l" << "hide-logger",QCoreApplication::translate("main", "Start with hidden log window"));
 parser.addOption(hideLoggerOption);
257

258
259
 QCommandLineOption hideToolboxOption(QStringList() << "t" << "hide-toolbox",QCoreApplication::translate("main", "Start with hidden toolbox"));
 parser.addOption(hideToolboxOption);
260

261
262
 QCommandLineOption noSplashOption("no-splash",QCoreApplication::translate("main", "Hide splash screen"));
 parser.addOption(noSplashOption);
263

264
265
 QCommandLineOption polyMeshOption("p",QCoreApplication::translate("main", "Open files as PolyMeshes"));
 parser.addOption(polyMeshOption);
266

267
268
 QCommandLineOption remotePortOption("remote-port",QCoreApplication::translate("main", "Remote port"),"portnumber");
 parser.addOption(remotePortOption);
269

270
271
 QCommandLineOption coreProfileOption("core-profile",QCoreApplication::translate("main", "OpenGL Core Profile Mode"));
 parser.addOption(coreProfileOption);
272
273
274
275
276
277
278
 
 QCommandLineOption glVersionOption("glVersion",QCoreApplication::translate("main","Request OpenGL version <major>.<minor> "),QCoreApplication::translate("main","< 1.0 | 1.1 | ... | 4.6 >"));
 parser.addOption(glVersionOption);
 
 QCommandLineOption samplesOption("samples",QCoreApplication::translate("main","Overwrite multisampling sample count"),QCoreApplication::translate("main","< 0 | 1 | 2 | ... | 16 >"));
 parser.addOption(samplesOption);
 
279
280
281
 QCommandLineOption glStereoOption("glStereo",QCoreApplication::translate("main","Overwrite OpenGL Stereo setting"),QCoreApplication::translate("main","< true | false >"));
 parser.addOption(glStereoOption);
 
282
 QCommandLineOption profileOption("profile",QCoreApplication::translate("main","Request OpenGL context profile <profile> with profile set as compat or core"),QCoreApplication::translate("main","< compat | core >"));
283
 parser.addOption(profileOption);
284
285
286
287

 QCommandLineOption pluginOptionsOption(QStringList() << "o" << "pluginoptions",QCoreApplication::translate("main", "Pass options to plugins"), "key1=value1;key2=value2;...");
 parser.addOption(pluginOptionsOption);

288
289
 const QCommandLineOption helpOption = parser.addHelpOption();
 const QCommandLineOption versionOption = parser.addVersionOption();
Dirk Wilden's avatar
Dirk Wilden committed
290
291


292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
 // Now parse the command line
 if (!parser.parse(QCoreApplication::arguments())) {
   *errorMessage = parser.errorText();
   return CommandLineError;
 }

 if (parser.isSet(helpOption))
   return CommandLineHelpRequested;

 if (parser.isSet(versionOption))
   return CommandLineVersionRequested;

 if (parser.isSet(debugOption)) {
   OpenFlipper::Options::debug(true);
 }

 if (parser.isSet(stereoOption)) {
   OpenFlipper::Options::stereo(false);
 }

 if (parser.isSet(batchOption)) {
   OpenFlipper::Options::nogui(true);
 }

 if (parser.isSet(logConsoleOption)) {
   OpenFlipper::Options::logToConsole(true);
 }

 if (parser.isSet(remoteControlOption)) {
   OpenFlipper::Options::remoteControl(true);
 }

 if (parser.isSet(fulscreenOption)) {
   OpenFlipperSettings().setValue("Core/Gui/fullscreen",true);
 }

 if (parser.isSet(hideLoggerOption)) {
   OpenFlipper::Options::loggerState(OpenFlipper::Options::Hidden);
 }

 if (parser.isSet(hideToolboxOption)) {
   OpenFlipperSettings().setValue("Core/Gui/ToolBoxes/hidden",true);
 }

 if (parser.isSet(noSplashOption)) {
   OpenFlipperSettings().setValue("Core/Gui/splash",false);
 }

 if (parser.isSet(polyMeshOption)) {
   openPolyMeshes = true;
 }

 if (parser.isSet(remotePortOption)) {
   const QString port = parser.value("remote-port");
   std::cerr << "Got port option : " << port.toStdString() << std::endl;
   OpenFlipper::Options::remoteControl(port.toInt());
348
 }
349
350
351
352
353
354
355
356
357
358
 if(parser.isSet("samples"))
   OpenFlipper::Options::samples(parser.value("samples").toInt(),true);
 if(parser.isSet("glVersion"))
 {
   QStringList values = parser.value("glVersion").split(".");
   QPair<int,int> version(
          values[0].toInt(),
          values[1].toInt());
   OpenFlipper::Options::glVersion(version,true);
 }
359
360
361
 
 if(parser.isSet("glStereo"))
   OpenFlipper::Options::glStereo(parser.value("glStereo")=="true");
362

363
364
 if(parser.value(profileOption)=="core")
 {
365
     OpenFlipper::Options::coreProfile(true, true);
366
367
368
369
370
 }
 else
 {
     if(parser.value(profileOption)=="compat")
     {
371
         OpenFlipper::Options::coreProfile(false, true);
372
373
     }
 }
374
 if(parser.isSet(coreProfileOption)) {
375
   OpenFlipper::Options::coreProfile(true, true);
376
 }
377
378
379
380
381
382
383
 if(parser.isSet(pluginOptionsOption))
 {
   QStringList poptions = parser.value(pluginOptionsOption).split(";");
   QVector<QPair<QString, QString>> pcloptions;
   for(auto s : poptions)
   {
       auto kvp = s.split("=");
384
385
386
387
388

       // Only consider terms of the kind "key=value"
       if(kvp.size() != 2u)
           continue;

389
390
391
392
393
394
       auto key = kvp[0];
       auto value = kvp[1];
       pcloptions.push_back({key, value});
   }
   PluginFunctions::setPluginCommandLineOptions(pcloptions);
 }
395

396
 return CommandLineOk;
Dirk Wilden's avatar
Dirk Wilden committed
397
398
}

399
400
// Detector for OpenGL
#include "OpenGL/OpenGLDetection.hh"
401

Dirk Wilden's avatar
Dirk Wilden committed
402
403
int main(int argc, char **argv)
{
404
405
406
407
408
409
410
#ifdef _WIN32
  // This make crashes visible - without them, starting the
  // application from cmd.exe or powershell can surprisingly hide
  // any signs of a an application crash!
  SetErrorMode(0); // 0: Use the system default, which is to display all error dialog boxes.
#endif

411

412
413
  // Remove -psn_0_xxxxx argument which is automatically
  // attached by MacOSX
Mike Kremer's avatar
   
Mike Kremer committed
414
  for (int i = 0; i < argc; i++) {
415
416
417
418
419
    if(strlen(argv[i]) > 4) {
      if( ( (argv[i])[0] == '-' ) &&
        ( (argv[i])[1] == 'p' ) &&
        ( (argv[i])[2] == 's' ) &&
        ( (argv[i])[3] == 'n' ) ) {
Jan Möbius's avatar
Jan Möbius committed
420
421
        argc--;
        argv[i] = (char *)"";
422
423
424
      }
    }
  }
Jan Möbius's avatar
Jan Möbius committed
425

Dirk Wilden's avatar
Dirk Wilden committed
426
427
428
  OpenFlipper::Options::argc(&argc);
  OpenFlipper::Options::argv(&argv);

429
  // Set organization and application names
430
  QCoreApplication::setOrganizationName("VCI");
431
432
  QCoreApplication::setApplicationName(TOSTRING(PRODUCT_STRING));
  QCoreApplication::setApplicationVersion(OpenFlipper::Options::coreVersion());
Dirk Wilden's avatar
Dirk Wilden committed
433

434
435
436
437
  // initialize a core application to check for commandline parameters
  QCoreApplication* coreApp = new QCoreApplication(argc, argv);

  OpenFlipper::Options::initializeSettings();
438
439
440

  QCommandLineParser parser;
  QString errorMessage;
Dirk Wilden's avatar
Dirk Wilden committed
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
  // parse command line options
  switch (parseCommandLine(parser, &errorMessage)) {
  case CommandLineOk:
	  break;
  case CommandLineError:
	  fputs(qPrintable(errorMessage), stderr);
	  fputs("\n\n", stderr);
	  fputs(qPrintable(parser.helpText()), stderr);
	  return 1;
  case CommandLineVersionRequested:
	  printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
		  qPrintable(QCoreApplication::applicationVersion()));
	  return 0;
  case CommandLineHelpRequested:
	  parser.showHelp();
	  Q_UNREACHABLE();
  }

  // only one application is allowed so delete the core application
  // once cmdline parsing is done
  delete coreApp;



466
467
468
469
#ifdef WIN32
  //attach a console if necessary
  attachConsole();
#endif
Dirk Wilden's avatar
Dirk Wilden committed
470

471
#ifndef NO_CATCH_SIGSEGV
Dirk Wilden's avatar
Dirk Wilden committed
472
473
  // Set a handler for segfaults
  std::signal(SIGSEGV, segfaultHandling);
474
#endif
Dirk Wilden's avatar
Dirk Wilden committed
475

Jan Möbius's avatar
Jan Möbius committed
476
  OpenFlipper::Options::windowTitle(TOSTRING(PRODUCT_STRING)" v" + OpenFlipper::Options::coreVersion());
477

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

Jan Möbius's avatar
 
Jan Möbius committed
480
    // OpenGL check
481
    QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
482

483
484
    // Try creating a valid OpenGL context
    /******************************/
485

486
487
    // Get a valid context format
    QSurfaceFormat resultFormat = getContextFormat();
488

489
490
491
492
493
    // Set temporary(!) OpenGL settings
    OpenFlipper::Options::samples(resultFormat.samples(), true);
    OpenFlipper::Options::glStereo(resultFormat.stereo(), true);
    OpenFlipper::Options::glVersion(resultFormat.version(), true);
    OpenFlipper::Options::coreProfile(resultFormat.profile() == QSurfaceFormat::CoreProfile, true);
494

495
496
    // Create the actual context
    QSurfaceFormat::setDefaultFormat(resultFormat);
497
    QApplication app(argc, argv);
498
499
500
    QOffscreenSurface *surface = new QOffscreenSurface();
    surface->create();

501
    // Make the globally shared OpenGLContext current
502
    QOpenGLContext::globalShareContext()->makeCurrent(surface);
503
    /******************************/
504
505


506
    // Check whether there is OpenGL support. If not, return.
Jan Möbius's avatar
 
Jan Möbius committed
507
508
509
510
    if ( !QGLFormat::hasOpenGL() ) {
      std::cerr << "This system has no OpenGL support.\n";
      return -1;
    }
511

Jan Möbius's avatar
 
Jan Möbius committed
512
513
    // create core ( this also reads the ini files )
    Core * w = new Core( );
514
515
516
#ifdef PYTHON_ENABLED
    setCorePointer(w);
#endif
517

518
    QString tLang = OpenFlipperSettings().value("Core/Language/Translation","en_US").toString();
519
520
521
522

    if (tLang == "locale")
      tLang = QLocale::system().name();

523
524
    // Install translator for qt internals
    QTranslator qtTranslator;
Jan Möbius's avatar
Jan Möbius committed
525
    qtTranslator.load("qt_" + tLang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
526
527
528
    app.installTranslator(&qtTranslator);
    
    // install translator for Core Application
Dirk Wilden's avatar
Dirk Wilden committed
529
530
531
532
533
534
535
536
537
538
539
540
    QString translationDir = OpenFlipper::Options::translationsDirStr() + QDir::separator();
    QDir dir(translationDir);
    dir.setFilter(QDir::Files);

    QFileInfoList list = dir.entryInfoList();

    for (int i = 0; i < list.size(); ++i) {
      QFileInfo fileInfo = list.at(i);

      if ( fileInfo.baseName().contains(tLang) ){
        QTranslator* myAppTranslator = new QTranslator();

schultz's avatar
schultz committed
541
542
        if ( myAppTranslator->load( fileInfo.filePath() ) )
        {    
Dirk Wilden's avatar
Dirk Wilden committed
543
          app.installTranslator(myAppTranslator);
schultz's avatar
schultz committed
544
545
546
        } else 
        {
  	        delete myAppTranslator;
Dirk Wilden's avatar
Dirk Wilden committed
547
548
549
        }
      }
     }
Jan's avatar
Jan committed
550
551
552
553

    #ifndef __APPLE__
    initGlew();
    #endif
554
555
556
557

    // After setting all Options from command line, build the real gui
    w->init();

558
559
560
561
562
    const QStringList positionalArguments = parser.positionalArguments();

    for ( auto file: positionalArguments ) {
      w->commandLineOpen(file, openPolyMeshes);
    }
563

Jan Möbius's avatar
 
Jan Möbius committed
564
    return app.exec();
565

Jan Möbius's avatar
 
Jan Möbius committed
566
  } else {
567

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

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

573
574
575
576
577

#ifdef PYTHON_ENABLED
    setCorePointer(w);
#endif

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

581
582
583
584
585
    const QStringList positionalArguments = parser.positionalArguments();

    for ( auto file: positionalArguments ) {
      w->commandLineOpen(file, openPolyMeshes);
    }
586

Dirk Wilden's avatar
Dirk Wilden committed
587
    return app.exec();
Jan Möbius's avatar
 
Jan Möbius committed
588
589
590
591
  }

  return 0;
}