Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
OpenFlipper.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51
52 // Mainwindow
53
54 #include "OpenFlipper/Core/Core.hh"
55 #include "common/glew_wrappers.hh"
56
57 // Qt
58 #include <qgl.h>
59
60 // stdc++
61 #include <csignal>
62
63 #include <OpenFlipper/SimpleOpt/SimpleOpt.h>
64
65 #if ( defined(WIN32))
66 #define NO_EXECINFO
67 #endif
68
69 #ifndef NO_EXECINFO
70 #include <execinfo.h>
71 #endif
72
73 #ifdef USE_OPENMP
74 #endif
75
76 /* ==========================================================
77 *
78 * Stackwalker code. Used to get a backtrace if OpenFlipper
79 * crashes under windows
80 *
81 * ==========================================================*/
82
83
84 #ifdef WIN32
85 #include "StackWalker/StackWalker.hh"
86 #include <fstream>
87
88 class StackWalkerToConsole : public StackWalker
89 {
90 protected:
91 virtual void OnOutput(LPCSTR szText)
92 {
93 // Writes crash dump to .OpenFlipper config directory
94 std::ofstream crashFile;
95 QString crashName = OpenFlipper::Options::configDirStr() + QDir::separator() + "CrashDump.txt";
96 crashFile.open(crashName.toLatin1(),std::ios::out | std::ios::app);
97 crashFile << szText;
98 crashFile.close();
99 }
100 };
101 #endif
102
103
104 /* ==========================================================
105 *
106 * Console for Windows to get additional output written via
107 * cerr, cout, ... that is not forwarded to log window
108 *
109 * ==========================================================*/
110
111 // Includes for windows debugging console
112 #ifdef WIN32
113 #ifdef WIN_GET_DEBUG_CONSOLE
114 #include <fcntl.h>
115 #include <io.h>
116 #endif
117 #endif
118
119 #ifdef WIN32
120 #ifdef WIN_GET_DEBUG_CONSOLE
121 void getConsole() {
122 //Create a console for this application
123 AllocConsole();
124 //Redirect unbuffered STDOUT to the console
125 HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
126 int SystemOutput = _open_osfhandle(intptr_t(ConsoleOutput), _O_TEXT);
127 FILE *COutputHandle = _fdopen(SystemOutput, "w" );
128 *stdout = *COutputHandle;
129 setvbuf(stdout, NULL, _IONBF, 0);
130 //Redirect unbuffered STDERR to the console
131 HANDLE ConsoleError = GetStdHandle(STD_ERROR_HANDLE);
132 int SystemError = _open_osfhandle(intptr_t(ConsoleError), _O_TEXT);
133 FILE *CErrorHandle = _fdopen(SystemError, "w" );
134 *stderr = *CErrorHandle;
135 setvbuf(stderr, NULL, _IONBF, 0);
136 //Redirect unbuffered STDIN to the console
137 HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
138 int SystemInput = _open_osfhandle(intptr_t(ConsoleInput), _O_TEXT);
139 FILE *CInputHandle = _fdopen(SystemInput, "r" );
140 *stdin = *CInputHandle;
141 setvbuf(stdin, NULL, _IONBF, 0);
142 }
143 #endif
144 #endif
145
146 /* ==========================================================
147 *
148 * Linux function printing a full stack trace to the console
149 *
150 * ==========================================================*/
151 #ifndef NO_EXECINFO
152 void backtrace()
153 {
154 void *addresses[20];
155 char **strings;
156
157 int size = backtrace(addresses, 20);
158 strings = backtrace_symbols(addresses, size);
159 std::cerr << "Stack frames: " << size << std::endl;
160 for(int i = 0; i < size; i++)
161 std::cerr << i << ": " << strings[i] << std::endl;
162 free(strings);
163
164 }
165 #endif
166
167 /* ==========================================================
168 *
169 * General segfault handler. This function is called if OpenFlipper
170 * crashes
171 *
172 * ==========================================================*/
173 void segfaultHandling (int) {
174
175 // prevent infinite recursion if segfaultHandling() causes another segfault
176 std::signal(SIGSEGV, SIG_DFL);
177
178
179 std::cerr << "\n" << std::endl;
180 std::cerr << "\n" << std::endl;
181 std::cerr << "\33[31m" << "=====================================================" << std::endl;
182 std::cerr << "\33[31m" << "OpenFlipper or one of its plugins caused a Segfault." << std::endl;
183 std::cerr << "\33[31m" << "This should not happen,... Sorry :-(" << std::endl;
184 std::cerr << "\33[31m" << "=====================================================" << std::endl;
185 std::cerr << "\n" << std::endl;
186
187 // Linux Handler
188 #ifndef NO_EXECINFO
189 std::cerr << "\33[0m" << "Trying a backtrace to show what happened last: " << std::endl;
190 backtrace();
191
192 std::cerr << "\n" << std::endl;
193 std::cerr << "Backtrace completed, trying to abort now ..." << std::endl;
194 #endif
195
196 // Windows handler via StackWalker
197 #ifdef WIN32
198 StackWalkerToConsole sw;
199 sw.ShowCallstack();
200 #endif
201
202
203 std::cerr << "Trying to get additional information (This might fail if the memory is corrupted)." << std::endl;
204
205 if (OpenFlipper::Options::gui()) {
206 for ( unsigned int i = 0 ; i < 4 ; ++i) {
207 std::cerr << "DrawMode Viewer "<< i << " " << PluginFunctions::drawMode(i).description() << std::endl;
208 }
209 }
210
211 std::abort();
212 }
213
214 enum {OPT_HELP , OPT_STEREO, OPT_BATCH ,OPT_CONSOLE_LOG , OPT_DEBUGGING, OPT_FULLSCREEN,
215 OPT_HIDDDEN_LOGGER , OPT_NOSPLASH ,OPT_HIDDDEN_TOOLBOX , OPT_LOAD_POLYMESHES,
216 OPT_REMOTE, OPT_REMOTE_PORT};
217
218 CSimpleOpt::SOption g_rgOptions[] = {
219 { OPT_DEBUGGING , (char*) "--debug" , SO_NONE },
220 { OPT_HELP , (char*) "-?" , SO_NONE },
221 { OPT_HELP , (char*) "--help" , SO_NONE },
222 { OPT_HELP , (char*) "-h" , SO_NONE },
223 { OPT_STEREO , (char*) "--disable-stereo" , SO_NONE },
224 { OPT_BATCH , (char*) "-b" , SO_NONE },
225 { OPT_CONSOLE_LOG , (char*) "-c" , SO_NONE },
226 { OPT_CONSOLE_LOG , (char*) "--log-to-console" , SO_NONE },
227 { OPT_FULLSCREEN , (char*) "-f" , SO_NONE },
228 { OPT_HIDDDEN_LOGGER , (char*) "-l" , SO_NONE },
229 { OPT_NOSPLASH , (char*) "--no-splash" , SO_NONE },
230 { OPT_HIDDDEN_TOOLBOX , (char*) "-t" , SO_NONE },
231 { OPT_LOAD_POLYMESHES , (char*) "-p" , SO_NONE },
232 { OPT_REMOTE , (char*) "--remote-control" , SO_NONE },
233 { OPT_REMOTE_PORT , (char*) "--remote-port" , SO_REQ_SEP },
234 SO_END_OF_OPTIONS // END
235 };
236
237 void showHelp() {
238 std::cerr << "OpenFlipper [Options] <filenames> " << std::endl << std::endl;;
239 std::cerr << "Possible Options : " << std::endl;
240 std::cerr << std::endl;
241
242 std::cerr << "Load/Save Options:" << std::endl;
243 std::cerr << " -p \t: Open files as PolyMeshes" << std::endl;
244 std::cerr << std::endl;
245
246 std::cerr << "Gui Options:" << std::endl;
247 std::cerr << " -f \t\t: Start Fullscreen" << std::endl;
248 std::cerr << " -l \t\t: Start with hidden logger" << std::endl;
249 std::cerr << " -t \t\t: Start with hidden Toolbox" << std::endl;
250 std::cerr << " --no-splash \t: Disable splash screen" << std::endl;
251
252 std::cerr << " --disable-stereo \t: Disable Stereo Mode" << std::endl;
253 std::cerr << std::endl;
254
255 std::cerr << "Log options:" << std::endl;
256 std::cerr << " --log-to-console ( -c ) \t: Write logger window contents to console" << std::endl;
257 std::cerr << std::endl;
258
259 std::cerr << "Other options:" << std::endl;
260 std::cerr << " -b \t: Batch mode, you have to provide a script for execution" << std::endl;
261 std::cerr << " --remote-control \t: Batch mode accepting remote connections" << std::endl;
262
263 std::cerr << std::endl;
264
265
266 std::cerr << " -h \t: This help" << std::endl;
267 }
268
269
270
271
272
273
274 bool openPolyMeshes = false;
275 bool remoteControl = false;
276
277 bool parseCommandLineOptions(CSimpleOpt& args){
278
279 QString port;
280
281 // while there are arguments left to process
282 while (args.Next()) {
283
284 if (args.LastError() == SO_SUCCESS) {
285
286 switch (args.OptionId() ) {
287 case OPT_BATCH:
288 OpenFlipper::Options::nogui(true);
289 break;
290 case OPT_CONSOLE_LOG:
291 OpenFlipper::Options::logToConsole(true);
292 break;
293 case OPT_DEBUGGING:
294 OpenFlipper::Options::debug(true);
295 break;
296 case OPT_STEREO:
297 OpenFlipper::Options::stereo(false);
298 break;
299 case OPT_HIDDDEN_TOOLBOX:
300 OpenFlipperSettings().setValue("Core/Gui/ToolBoxes/hidden",true);
301 break;
302 case OPT_HIDDDEN_LOGGER:
303 OpenFlipper::Options::loggerState(OpenFlipper::Options::Hidden);
304 break;
305 case OPT_FULLSCREEN:
306 OpenFlipperSettings().setValue("Core/Gui/fullscreen",false);
307 break;
308 case OPT_LOAD_POLYMESHES:
309 openPolyMeshes = true;
310 break;
311 case OPT_NOSPLASH:
312 OpenFlipperSettings().setValue("Core/Gui/splash",false);
313 break;
314 case OPT_REMOTE:
315 OpenFlipper::Options::remoteControl(true);
316 break;
317 case OPT_REMOTE_PORT:
318 port = args.OptionArg();
319 std::cerr << "Got option : " << port.toStdString() << std::endl;
320 OpenFlipper::Options::remoteControl(port.toInt());
321 break;
322 case OPT_HELP:
323 showHelp();
324 return 0;
325 }
326 } else {
327 std::cerr << "Invalid argument: " << args.OptionText() << std::endl;
328 showHelp();
329 return false;
330 }
331 }
332 return true;
333 }
334
335 int main(int argc, char **argv)
336 {
337
338 // Remove -psn_0_xxxxx argument which is automatically
339 // attached by MacOSX
340 for (int i = 0; i < argc; i++) {
341 if(strlen(argv[i]) > 4) {
342 if( ( (argv[i])[0] == '-' ) &&
343 ( (argv[i])[1] == 'p' ) &&
344 ( (argv[i])[2] == 's' ) &&
345 ( (argv[i])[3] == 'n' ) ) {
346 argc--;
347 argv[i] = (char *)"";
348 }
349 }
350 }
351
352 OpenFlipper::Options::argc(&argc);
353 OpenFlipper::Options::argv(&argv);
354
355 CSimpleOpt argBatch(argc, argv, g_rgOptions);
356
357 //check only batchMode before the core is created
358 while (argBatch.Next())
359 if (argBatch.OptionId() == OPT_BATCH ){
360 OpenFlipper::Options::nogui(true);
361 break;
362 }
363
364 CSimpleOpt args(argc, argv, g_rgOptions);
365
366 #ifndef NO_CATCH_SIGSEGV
367 // Set a handler for segfaults
368 std::signal(SIGSEGV, segfaultHandling);
369 #endif
370
371 OpenFlipper::Options::windowTitle(TOSTRING(PRODUCT_STRING)" v" + OpenFlipper::Options::coreVersion());
372
373 #ifdef WIN32
374 #ifdef WIN_GET_DEBUG_CONSOLE
375 getConsole();
376 #endif
377 #endif
378
379 if ( !OpenFlipper::Options::nogui() ) {
380
381 // OpenGL check
382 QApplication::setColorSpec( QApplication::CustomColor );
383 QApplication app(argc,argv);
384
385 #ifdef __APPLE__
386 // Set organization and application names
387 QCoreApplication::setOrganizationName("rwth-aachen.de");
388 QCoreApplication::setApplicationName("graphics.openflipper");
389 #endif
390
391 if ( !QGLFormat::hasOpenGL() ) {
392 std::cerr << "This system has no OpenGL support.\n";
393 return -1;
394 }
395
396 #ifndef __APPLE__
397 glutInit(&argc,argv);
398 #endif
399
400 // create core ( this also reads the ini files )
401 Core * w = new Core( );
402
403 if ( !parseCommandLineOptions(args) ) {
404 delete w;
405 return 1;
406 }
407
408 QString tLang = OpenFlipperSettings().value("Core/Language/Translation","en_US").toString();
409
410 if (tLang == "locale")
411 tLang = QLocale::system().name();
412
413 // Install translator for qt internals
414 QTranslator qtTranslator;
415 // std::cerr << "Loading qt translations from: " << QLibraryInfo::location(QLibraryInfo::TranslationsPath).toStdString() << std::endl;
416 // if ( qtTranslator.load("qt_" + tLang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) )
417 // std::cerr << "Loaded" << std::endl;
418 // std::cerr << "Loading qt translations from: " << QLibraryInfo::location(QLibraryInfo::TranslationsPath).toStdString() << std::endl;
419 qtTranslator.load("qt_" + tLang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
420 // std::cerr << "Loaded" << std::endl;
421
422 app.installTranslator(&qtTranslator);
423
424 // install translator for Core Application
425 QString translationDir = OpenFlipper::Options::translationsDirStr() + QDir::separator();
426
427 // std::cerr << "Loading own translations from: " << QString(translationDir + " (" + tLang + ")").toStdString() << std::endl;
428
429 QDir dir(translationDir);
430 dir.setFilter(QDir::Files);
431
432 QFileInfoList list = dir.entryInfoList();
433
434 for (int i = 0; i < list.size(); ++i) {
435 QFileInfo fileInfo = list.at(i);
436
437 if ( fileInfo.baseName().contains(tLang) ){
438 QTranslator* myAppTranslator = new QTranslator();
439
440 if ( myAppTranslator->load( fileInfo.filePath() ) ){
441 // std::cerr << "Loaded " << fileInfo.fileName().toStdString() << std::endl;
442
443 app.installTranslator(myAppTranslator);
444 } else {
445 delete myAppTranslator;
446 }
447 }
448 }
449
450 // After setting all Options from command line, build the real gui
451 w->init();
452
453 #ifndef __APPLE__
454 initGlew();
455 #endif
456
457 for ( int i = 0 ; i < args.FileCount(); ++i )
458 w->commandLineOpen(args.File(i), openPolyMeshes);
459
460 return app.exec();
461
462 } else {
463
464 QCoreApplication app(argc,argv);
465
466 #ifdef __APPLE__
467 // Set organization and application names
468 QCoreApplication::setOrganizationName("rwth-aachen.de");
469 QCoreApplication::setApplicationName("graphics.openflipper");
470 #endif
471
472 // create widget ( this also reads the ini files )
473 Core * w = new Core( );
474
475 if ( !parseCommandLineOptions(args) ) {
476 delete w;
477 return 1;
478 }
479
480 // After setting all Options from command line, build the real gui
481 w->init();
482
483 for ( int i = 0 ; i < args.FileCount(); ++i )
484 w->commandLineScript(args.File(i));
485
486 return app.exec();
487 }
488
489 return 0;
490 }
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:938
PluginFunctions::drawMode
ACG::SceneGraph::DrawModes::DrawMode drawMode(int _viewer)
Get the current draw Mode of a Viewer.
Definition: PluginFunctions.cc:454
Core::init
void init()
Second initialization stage.
Definition: Core.cc:193
Core::commandLineOpen
void commandLineOpen(const char *_filename, bool _asPolyMesh)
Load an object from the commandline on application start.
Definition: openFunctions.cc:104
StackWalker
Definition: StackWalker.hh:52
Core
Definition: Core.hh:139
ACG::SceneGraph::DrawModes::DrawMode::description
std::string description() const
TOSTRING
#define TOSTRING(x)
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.hh:168
OpenFlipperQSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: OpenFlipperQSettings.cc:53
Core::commandLineScript
void commandLineScript(const char *_filename)
Load a script from the commandline on application start.
Definition: openFunctions.cc:119
Core.hh
OpenFlipperQSettings::setValue
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
Definition: OpenFlipperQSettings.cc:68