Core.cc 78.5 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
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
41
\*===========================================================================*/

42

Jan Möbius's avatar
 
Jan Möbius committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73





//=============================================================================
//
//  CLASS Core - IMPLEMENTATION
//
//=============================================================================


//== INCLUDES =================================================================

// -------------------- mview
#include "Core.hh"
// -------------------- ACG

#include <ACG/QtWidgets/QtFileDialog.hh>
// -------------------- Qt


#include "OpenFlipper/BasePlugin/KeyInterface.hh"
#include "OpenFlipper/BasePlugin/MouseInterface.hh"
#include "OpenFlipper/BasePlugin/PickingInterface.hh"
#include "OpenFlipper/BasePlugin/ToolboxInterface.hh"
#include "OpenFlipper/BasePlugin/TextureInterface.hh"
#include "OpenFlipper/BasePlugin/INIInterface.hh"

#include <OpenFlipper/common/RecentFiles.hh>

Jan Möbius's avatar
   
Jan Möbius committed
74
#include "OpenFlipper/BasePlugin/PluginFunctionsCore.hh"
Jan Möbius's avatar
 
Jan Möbius committed
75

Jan Möbius's avatar
Jan Möbius committed
76
77
#include "OpenFlipper/BasePlugin/RPCWrappers.hh"

Jan Möbius's avatar
 
Jan Möbius committed
78
79
#include <OpenMesh/Core/System/omstream.hh>

80
81
#include <OpenFlipper/common/BaseObjectCore.hh>
#include <OpenFlipper/common/TypesInternal.hh>
Jan Möbius's avatar
Jan Möbius committed
82

Isaak Lim's avatar
Isaak Lim committed
83
84
#include <OpenFlipper/widgets/messageBox/StaysOnTopMessageBox.hh>

85
86
#include <OpenFlipper/common/PluginStorage.hh>

87
88
89
#include <ACG/Scenegraph/MaterialNode.hh>
#include <ACG/Scenegraph/SeparatorNode.hh>

Jan Möbius's avatar
 
Jan Möbius committed
90
91
92
#define WIDGET_HEIGHT 800
#define WIDGET_WIDTH  800

93
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
94
95

/** \brief Constuctor for the Core Widget ( This is stage 1 , call init for stage 2)
96
 *
Jan Möbius's avatar
 
Jan Möbius committed
97
98
99
100
101
102
103
104
105
 * Initialization is working the following way:\n
 * - Setup basic paths \n
 * - Get Options from Option files ( While skipping the OpenFiles Sections as Core is not running )\n
 * - Jump back ( Stage two is done by calling init from main ) so CALL init!!
 * - This Two stage system allows using commandline options which override Option Files
*/
Core::
Core() :
  QObject(),
106
  capture_(false),
107
  processManager_(0),
Jan Möbius's avatar
 
Jan Möbius committed
108
  nextBackupId_(0),
Dirk Wilden's avatar
Dirk Wilden committed
109
  nextBackupGroupId_(0),
110
  objectRoot_(0),
111
112
  coreWidget_(0),
  splash_(0)
Jan Möbius's avatar
 
Jan Möbius committed
113
{
114

Dirk Wilden's avatar
Dirk Wilden committed
115
116
117
118
  //init logFile
  logStream_ = 0;
  logFile_ = 0;

Dirk Wilden's avatar
Dirk Wilden committed
119
120
  //init nodes
  root_node_scenegraph_ = new ACG::SceneGraph::SeparatorNode(0, "SceneGraph Root Node");
Jan Möbius's avatar
Jan Möbius committed
121
  
122
  // init global data node
Jan Möbius's avatar
Jan Möbius committed
123
  root_node_scenegraph_global_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_ , "SceneGraph Rendered Root Node");
124
  
Jan Möbius's avatar
Jan Möbius committed
125
  // This separator will manage the cores nodes
126
  core_nodes_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Core Nodes");
Jan Möbius's avatar
Jan Möbius committed
127
128
129
130
  
  // Coordsys rendering nodes
  coordsysMaterialNode_ = new ACG::SceneGraph::MaterialNode(core_nodes_,"Coordsys Material Node");
  coordsysNode_ = new ACG::SceneGraph::CoordsysNode(coordsysMaterialNode_,"Core Coordsys Node");  
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
131
  coordsysNode_->setTraverseMode (BaseNode::NodeFirst | BaseNode::SecondPass);
Jan Möbius's avatar
Jan Möbius committed
132
  
Jan Möbius's avatar
Jan Möbius committed
133
  // Separator handling the nodes for data
134
  dataSeparatorNode_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Data Separator Root Node");
Jan Möbius's avatar
Jan Möbius committed
135
  
Jan Möbius's avatar
Jan Möbius committed
136
  // Separator handling the nodes for data
Jan Möbius's avatar
Jan Möbius committed
137
  dataRootNode_      = new ACG::SceneGraph::SeparatorNode(dataSeparatorNode_, "Data Root Node");
Dirk Wilden's avatar
Dirk Wilden committed
138

Jan Möbius's avatar
 
Jan Möbius committed
139
140
141
   // Add ViewMode All
  ViewMode* vm = new ViewMode();
  vm->name = "All";
Jan Möbius's avatar
Jan Möbius committed
142
  vm->icon = "viewmode_all.png";
Jan Möbius's avatar
 
Jan Möbius committed
143
  vm->custom = false;
Jan Möbius's avatar
Jan Möbius committed
144
  vm->visibleToolboxes = QStringList();
145

Jan Möbius's avatar
 
Jan Möbius committed
146
147
  viewModes_.push_front(vm);

Dirk Wilden's avatar
Dirk Wilden committed
148
149
150
  //init ViewerProperties (always for 4 Viewers!)
  std::vector< Viewer::ViewerProperties* > viewerProperties;

151
  for (int i=0; i < 4; i++) {
152
    Viewer::ViewerProperties* viewerProperty = new Viewer::ViewerProperties(i);
153
154
155
    viewerProperty->snapshotBaseFileName("snap-Viewer-" + QString::number(i) + ".png");
    viewerProperties.push_back( viewerProperty );
  }
Dirk Wilden's avatar
Dirk Wilden committed
156
157
158

  PluginFunctions::setViewerProperties(viewerProperties);

159
160
161
162
163
164
  //set viewer defaults
  OpenFlipper::Options::defaultViewingDirection( PluginFunctions::VIEW_FREE,  0 );
  OpenFlipper::Options::defaultViewingDirection( PluginFunctions::VIEW_TOP,   1 );
  OpenFlipper::Options::defaultViewingDirection( PluginFunctions::VIEW_LEFT,  2 );
  OpenFlipper::Options::defaultViewingDirection( PluginFunctions::VIEW_FRONT, 3 );

Jan Möbius's avatar
 
Jan Möbius committed
165
166
  // Get all relevant Paths and Options from option files
  setupOptions();
Jan Möbius's avatar
Jan Möbius committed
167

168
169
  // set discriptions for scriptable slots
  setDescriptions();
170
171
172
  
  // Initialize the build in dataTypes
  initializeTypes();
Dirk Wilden's avatar
Dirk Wilden committed
173
174
175
  
  // Initialize the build in updateTypes
  initializeUpdateTypes();
Jan Möbius's avatar
 
Jan Möbius committed
176
177
}

178
179
180
/** \brief Second initialization stage
 *
 * This Stage does the following :\n
Jan Möbius's avatar
 
Jan Möbius committed
181
182
183
184
185
186
 * - Create the Core GUI Elements (Examiner, Toolbox,...)\n
 * - Create the MenuBar \n
 * - load the Plugins \n
 * - connect the Mouse slots \n
 * - Load all ini files (This includes the Global Option files) \n
 */
187
188
void
Core::init() {
Jan Möbius's avatar
Jan Möbius committed
189
190
191
  
  // Check library versions
  checkLibraryVersions();
192

Jan Möbius's avatar
 
Jan Möbius committed
193
  // Make root_node available to the plugins ( defined in PluginFunctions.hh)
Jan Möbius's avatar
Jan Möbius committed
194
  PluginFunctions::setDataSeparatorNodes( dataSeparatorNode_ );
195

196
  // Topmost node of the scenegraph
Jan Möbius's avatar
   
Jan Möbius committed
197
  PluginFunctions::setSceneGraphRootNode( root_node_scenegraph_ );
198
199
200
201
  
  // Node below the global status nodes. All nodes with global rendering
  // will be attached here.
  PluginFunctions::setSceneGraphRootNodeGlobal(root_node_scenegraph_global_);
Dirk Wilden's avatar
Dirk Wilden committed
202

Jan Möbius's avatar
 
Jan Möbius committed
203
  // Initialize the first object as the root Object for the object tree
204
  objectRoot_ =  dynamic_cast< BaseObject* > ( new GroupObject("ObjectRoot") );
Jan Möbius's avatar
 
Jan Möbius committed
205
  PluginFunctions::setDataRoot( objectRoot_ );
Jan Möbius's avatar
Jan Möbius committed
206
207
208
  
  // Bring up the object manager ( has to be done after the rootobject is created)
  connect(getObjectManager(),SIGNAL(newObject(int)), this ,SLOT(newObject(int)));
209
210
  
  connect(getObjectManager(),SIGNAL(deletedObject(int)), this ,SLOT(deletedObject(int)));
211

Jan Möbius's avatar
 
Jan Möbius committed
212
  if ( OpenFlipper::Options::gui() ) {
213

Jan Möbius's avatar
Jan Möbius committed
214
    // Initialize redraw timer. Will be used to restrict the rendering framerate.
215
216
217
218
    redrawTimer_ = new QTimer();
    redrawTimer_->setSingleShot(true);
    connect(redrawTimer_, SIGNAL(timeout()), this, SLOT(updateView()),Qt::DirectConnection);

219
220
221
222
223
224
225
226
    // Initialice scenegraph check timer. Will be used to check for changes in the scenegraph
    scenegraphCheckTimer_ = new QTimer();
    scenegraphCheckTimer_->setSingleShot(false);
    connect(scenegraphCheckTimer_, SIGNAL(timeout()), this, SLOT(checkScenegraphDirty()),Qt::DirectConnection);

    // Will measure the time between redraws
    redrawTime_ = new QTime();
    redrawTime_->start ();
227

228
    if ( OpenFlipperSettings().value("Core/Gui/splash",true).toBool() ) {
Jan Möbius's avatar
 
Jan Möbius committed
229
      QPixmap splashPixmap(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "splash.png");
230

231
      splash_ = new QSplashScreen(splashPixmap, Qt::SplashScreen | Qt::WindowStaysOnTopHint);
Jan Möbius's avatar
 
Jan Möbius committed
232
      splash_->show();
233

234
      splash_->showMessage(tr("Initializing mainwindow") ,
Jan Möbius's avatar
 
Jan Möbius committed
235
236
                          Qt::AlignBottom | Qt::AlignLeft , Qt::white);
    }
237

238
    coreWidget_ = new CoreWidget(viewModes_ , coreSlots_);
239

240
241
242
243
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxScrollArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolbox());

Jan Möbius's avatar
 
Jan Möbius committed
244
    connect(coreWidget_, SIGNAL(clearAll())           , this, SLOT(clearAll()));
245
    connect(coreWidget_, SIGNAL(loadMenu())           , this, SLOT(loadObject()));
Jan Möbius's avatar
 
Jan Möbius committed
246
    connect(coreWidget_, SIGNAL(addEmptyObjectMenu()) , this, SLOT(slotAddEmptyObjectMenu()));
247
248
249
250
    connect(coreWidget_, SIGNAL(saveMenu())           , this, SLOT(saveAllObjects()));
    connect(coreWidget_, SIGNAL(saveToMenu())         , this, SLOT(saveAllObjectsTo()));
    connect(coreWidget_, SIGNAL(loadIniMenu())        , this, SLOT(loadSettings()));
    connect(coreWidget_, SIGNAL(saveIniMenu())        , this, SLOT(saveSettings()));
251
    connect(coreWidget_, SIGNAL(applyOptions())       , this, SLOT(applyOptions()));
Dirk Wilden's avatar
Dirk Wilden committed
252
    connect(coreWidget_, SIGNAL(saveOptions())        , this, SLOT(saveOptions()));
Jan Möbius's avatar
 
Jan Möbius committed
253
    connect(coreWidget_, SIGNAL(recentOpen(QAction*)) , this, SLOT(slotRecentOpen(QAction*)));
254
    connect(coreWidget_, SIGNAL(exit())               , this, SLOT(slotExit()), Qt::QueuedConnection); // queue to avoid destroying the core widget during event handling
255

256
257
258

    connect( coreWidget_, SIGNAL( resizeViewers(int,int) ), this, SLOT( resizeViewers(int,int) ) );
    connect( coreWidget_, SIGNAL( resizeApplication(int,int) ), this, SLOT( resizeApplication(int,int) ) );
Dirk Wilden's avatar
Dirk Wilden committed
259
260
    connect( coreWidget_, SIGNAL( stopVideoCapture() ), this, SLOT( stopVideoCapture() ) );
    connect( coreWidget_, SIGNAL( startVideoCapture(QString,int,bool) ), this, SLOT( startVideoCapture(QString,int,bool) ) );
261
    connect( coreWidget_, SIGNAL( dragOpenFile(QString)), this, SLOT(loadObject(QString)));
262

Dirk Wilden's avatar
Dirk Wilden committed
263
    connect(coreWidget_, SIGNAL(showPlugins())       , this, SLOT(slotShowPlugins()));
264

Dirk Wilden's avatar
Dirk Wilden committed
265
    connect(coreWidget_, SIGNAL(call(QString,bool&)), this, SLOT(slotCall(QString,bool&)));
266
267
    
    connect( coreWidget_->logWidget_->openMeshFilterAction_,SIGNAL(toggled(bool)), this, SLOT(enableOpenMeshErrorLog(bool)) );
Dirk Wilden's avatar
Dirk Wilden committed
268

Jan Möbius's avatar
Jan Möbius committed
269
270
271
272
273
274
275
276
277
278
279
280
    QRect rect = QApplication::desktop()->screenGeometry();

    uint width = rect.width();
    if ( width > 1000 ) {
      width = 1000;
    }

    uint height = rect.height();
    if ( height > 1000 ) {
      height = 1000;
    }

Jan Möbius's avatar
Jan Möbius committed
281
282
283
#ifdef ARCH_DARWIN
    width = rect.width() - 300;
    height = rect.height() - 150;
Jan Möbius's avatar
Jan Möbius committed
284

Jan Möbius's avatar
Jan Möbius committed
285
//     coreWidget_->setMaximumSize( width, height  );
Jan Möbius's avatar
Jan Möbius committed
286
287
#endif

Jan Möbius's avatar
Jan Möbius committed
288
    coreWidget_->resize(width,height);
289
290


Jan Möbius's avatar
Jan Möbius committed
291
292
293
    // Sanity check for OpenGL capabilities!
    checkOpenGLCapabilities();

Jan Möbius's avatar
Jan Möbius committed
294
295
296
297

    QString titleInfo = OpenFlipper::Options::windowTitle();

    #ifdef DEBUG
298
      titleInfo = titleInfo + " [DEBUG]";
Jan Möbius's avatar
Jan Möbius committed
299
300
301
302
303
304
305
306
307
    #endif

    if ( OpenFlipper::Options::coreProfile() )
      titleInfo = titleInfo + " CoreProfile";
    else
      titleInfo = titleInfo + " CompatProfile";

    coreWidget_->setWindowTitle( titleInfo );

Jan Möbius's avatar
 
Jan Möbius committed
308
  }
309

Jan Möbius's avatar
 
Jan Möbius committed
310
311
312
313
  // ======================================================================
  // Create intermediate logger class for Core which will mangle the output
  // ======================================================================
  PluginLogger* newlog = new PluginLogger("Core");
314

Jan Möbius's avatar
 
Jan Möbius committed
315
316
  loggers_.push_back(newlog);
  connect(this,SIGNAL(log(Logtype, QString )),newlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
317
318
  connect(this,SIGNAL(log(QString )),newlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Jan Möbius's avatar
 
Jan Möbius committed
319
320
321
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
322

Jan Möbius's avatar
 
Jan Möbius committed
323
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
324

Dirk Wilden's avatar
Dirk Wilden committed
325
326
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
327
328
329
330
331
332
333

  // ======================================================================
  // Create a logger class for CoreWidget
  // ======================================================================

  if ( OpenFlipper::Options::gui() ){
    PluginLogger* widgetlog = new PluginLogger("CoreWidget");
334

Dirk Wilden's avatar
Dirk Wilden committed
335
336
    loggers_.push_back(widgetlog);
    connect(coreWidget_,SIGNAL(log(Logtype, QString )),widgetlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
337
338
    connect(coreWidget_,SIGNAL(log(QString )),widgetlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Dirk Wilden's avatar
Dirk Wilden committed
339
340
341
    // Connect it to the Master logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
342
343
    // connection to file logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
344
  }
345

Jan Möbius's avatar
 
Jan Möbius committed
346
347
348
349
350
351
  // ======================================================================
  // Catch OpenMesh Error logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGERR);
  omerr().connect(*newlog);
  omerr().disconnect(std::cerr);
352

Jan Möbius's avatar
 
Jan Möbius committed
353
  loggers_.push_back(newlog);
354

Jan Möbius's avatar
 
Jan Möbius committed
355
356
357
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
358

Jan Möbius's avatar
 
Jan Möbius committed
359
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
360
361
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
362

Jan Möbius's avatar
 
Jan Möbius committed
363
364
365
366
367
368
  // ======================================================================
  // Catch OpenMesh omout logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGINFO);
  omout().connect(*newlog);
  omout().disconnect(std::cout);
369

Jan Möbius's avatar
 
Jan Möbius committed
370
  loggers_.push_back(newlog);
371

Jan Möbius's avatar
 
Jan Möbius committed
372
373
374
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
375

Jan Möbius's avatar
 
Jan Möbius committed
376
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
377
378
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
379

Jan Möbius's avatar
 
Jan Möbius committed
380
381
382
383
384
  // ======================================================================
  // Catch OpenMesh omlog logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGOUT);
  omlog().connect(*newlog);
385

Jan Möbius's avatar
 
Jan Möbius committed
386
  loggers_.push_back(newlog);
387

Jan Möbius's avatar
 
Jan Möbius committed
388
389
390
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
391

Jan Möbius's avatar
 
Jan Möbius committed
392
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
393
394
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
395

Jan Möbius's avatar
 
Jan Möbius committed
396
397
398
399
  // ======================================================================
  // Log Scripting stuff through a separate logger
  // ======================================================================
  newlog = new PluginLogger("Scripting",LOGOUT);
400

Jan Möbius's avatar
 
Jan Möbius committed
401
  loggers_.push_back(newlog);
402

Jan Möbius's avatar
 
Jan Möbius committed
403
404
405
  // Connect it to the Master logger
  if ( OpenFlipper::Options::gui() )
    connect(newlog,SIGNAL(log(Logtype, QString )),coreWidget_,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
406

Jan Möbius's avatar
 
Jan Möbius committed
407
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
408
  // connection to file logger
409
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
410

Jan Möbius's avatar
 
Jan Möbius committed
411
  // connect signal to logger
412
413
  connect(this,SIGNAL(scriptLog(QString )),newlog,SLOT(slotLog(QString )),Qt::DirectConnection);

414
  
Jan Möbius's avatar
 
Jan Möbius committed
415
  // ======================================================================
416
  // Set up QtScript Environment
Jan Möbius's avatar
 
Jan Möbius committed
417
  // ======================================================================
418
  
Jan Möbius's avatar
Jan Möbius committed
419
420
421
  // Set a reference to the scriptengine for simple rpc calls
  RPC::setScriptEngine(&scriptEngine_);

Jan Möbius's avatar
Jan Möbius committed
422
  connect(&scriptEngine_, SIGNAL( signalHandlerException(const QScriptValue &) ), this, SLOT( slotScriptError(const QScriptValue &) ));
423

Jan Möbius's avatar
 
Jan Möbius committed
424
425
  // process Events every 500 msecs during script execution
  scriptEngine_.setProcessEventsInterval( 500 );
426

Jan Möbius's avatar
 
Jan Möbius committed
427
428
429
430
  // Register own print function :
  QScriptValue printFunction = scriptEngine_.newFunction(myPrintFunction);
  printFunction.setProperty("textedit",scriptEngine_.newQObject(this));
  scriptEngine_.globalObject().setProperty("print", printFunction);
431

432
433
434
  // Register print to file function :
  QScriptValue printToFileFunc = scriptEngine_.newFunction(printToFileFunction);
  scriptEngine_.globalObject().setProperty("printToFile", printToFileFunc);
435
  scriptingFunctions_.push_back( "-.printToFile(QString,QString)" );
436

Jan Möbius's avatar
Jan Möbius committed
437
438
439
440
441
442
  // Register help function :
  QScriptValue helpFunc = scriptEngine_.newFunction(helpFunction);
  helpFunc.setProperty("core",scriptEngine_.newQObject(this));
  scriptEngine_.globalObject().setProperty("help", helpFunc);
  scriptingFunctions_.push_back( "-.help(QString)" );

443
444
445
446
447
448
449
450
451
  // Register IdList Type to scripting Engine
  qScriptRegisterSequenceMetaType< IdList >(&scriptEngine_);
  
  // Register Vector of ints Type to scripting Engine
  qScriptRegisterSequenceMetaType< QVector< int > >(&scriptEngine_);
  
  //==========================================================================
  // Register the 3d Vector Type to the core ( is Vec3d )
  //==========================================================================
452
453
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueVector,
Jan Möbius's avatar
 
Jan Möbius committed
454
455
                          fromScriptValueVector,
                          scriptEngine_.newQObject(&vec3dPrototype_));
456
                          
Jan Möbius's avatar
 
Jan Möbius committed
457
  // set a constructor to allow creation via Vector(x,y,z)
Jan Möbius's avatar
Jan Möbius committed
458
459
460
461
462
463
464
  QScriptValue ctorVec3 = scriptEngine_.newFunction(createVector);
  scriptEngine_.globalObject().setProperty("Vector", ctorVec3);

  //==========================================================================
  // Register the 4d Vector Type to the core ( is Vec4d )
  //==========================================================================
  qScriptRegisterMetaType(&scriptEngine_,
465
466
                          toScriptValueVector4,
                          fromScriptValueVector4,
Jan Möbius's avatar
Jan Möbius committed
467
468
469
470
471
                          scriptEngine_.newQObject(&vec4dPrototype_));

  // set a constructor to allow creation via Vector(x,y,z)
  QScriptValue ctorVec4 = scriptEngine_.newFunction(createVector4);
  scriptEngine_.globalObject().setProperty("Vector4", ctorVec4);
472
473
474
475
                          
  //==========================================================================
  // Register the DataType Class to the core
  //==========================================================================
476

477
  // Register DataType in QScriptEngine
478
  qScriptRegisterMetaType<DataType>(&scriptEngine_,
479
480
481
482
483
                          toScriptValueDataType,
                          fromScriptValueDataType,
                          scriptEngine_.newQObject(&DataTypePrototype_));
                          
  // set a constructor to allow creation via DataType(uint)
484
485
486
487
488
489
  QScriptValue dataTypector = scriptEngine_.newFunction(createDataType);
  scriptEngine_.globalObject().setProperty("DataType", dataTypector);     
  
  //==========================================================================
  // Register the Matrix Class to the core
  //==========================================================================
490

Jan Möbius's avatar
 
Jan Möbius committed
491
  // Register Matrix Type to scripting Engine ( is ACG::Matrix4x4d )
492
493
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueMatrix4x4 ,
Jan Möbius's avatar
 
Jan Möbius committed
494
495
                          fromScriptValueMatrix4x4,
                          scriptEngine_.newQObject(&matrix4x4Prototype_));
496

Jan Möbius's avatar
 
Jan Möbius committed
497
498
499
  // set a constructor to allow creation via Matrix(x,y,z)
  QScriptValue matrix4x4ctor = scriptEngine_.newFunction(createMatrix4x4);
  scriptEngine_.globalObject().setProperty("Matrix4x4", matrix4x4ctor);
500

501
502
503
504
  //==========================================================================
  //  Collect Core scripting information
  //==========================================================================

Jan Möbius's avatar
 
Jan Möbius committed
505
506
507
508
509
510
  QScriptValue scriptInstance = scriptEngine_.newQObject(this,
                                                         QScriptEngine::QtOwnership,
                                                         QScriptEngine::ExcludeChildObjects |
                                                         QScriptEngine::ExcludeSuperClassMethods |
                                                         QScriptEngine::ExcludeSuperClassProperties
                                                         );
511

Jan Möbius's avatar
 
Jan Möbius committed
512
  scriptEngine_.globalObject().setProperty("core", scriptInstance);
513

Jan Möbius's avatar
 
Jan Möbius committed
514
515
516
  QScriptValueIterator it(scriptInstance);
  while (it.hasNext()) {
    it.next();
517

Jan Möbius's avatar
 
Jan Möbius committed
518
    /// Skip all signals for function calls
519
    if ( checkSignal( this, it.name().toLatin1() ) )
Jan Möbius's avatar
 
Jan Möbius committed
520
      continue;
521

Jan Möbius's avatar
 
Jan Möbius committed
522
    scriptingFunctions_.push_back( "core." + it.name() );
523

Jan Möbius's avatar
 
Jan Möbius committed
524
  }
525

Jan Möbius's avatar
 
Jan Möbius committed
526
  loadPlugins();
527

Jan Möbius's avatar
 
Jan Möbius committed
528
  if ( OpenFlipper::Options::gui() ) {
529

Dirk Wilden's avatar
Dirk Wilden committed
530
531
532
    //register keyBinding for all scripting slots
    coreWidget_->slotRegisterSlotKeyBindings();

533
534
535
    //get keyAssignments from config files
    restoreKeyBindings();

Jan Möbius's avatar
Marlin:    
Jan Möbius committed
536
537
    if ( OpenFlipper::Options::currentViewMode( ) != "" )
      coreWidget_->setViewMode( OpenFlipper::Options::currentViewMode() );
Jan Möbius's avatar
 
Jan Möbius committed
538
539
    else
      coreWidget_->setViewMode("All");
540

541
    // Set the renderer to the one stored in the settings or to default
542
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i ) {
Jan Möbius's avatar
Jan Möbius committed
543
544
545
546
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalMouseEvent(QMouseEvent*)),
              this                              , SLOT(slotMouseEvent(QMouseEvent*)));
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalMouseEventIdentify(QMouseEvent*)),
              this                              , SLOT(slotMouseEventIdentify(QMouseEvent*)));
Jan Möbius's avatar
Mike:    
Jan Möbius committed
547
548
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalMouseEventLight(QMouseEvent*)),
              this                              , SLOT(slotMouseEventLight(QMouseEvent*)));
Jan Möbius's avatar
Jan Möbius committed
549
550
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalWheelEvent(QWheelEvent *, const std::string &)),
              this                              , SLOT(slotWheelEvent(QWheelEvent *, const std::string &)));
Jan Möbius's avatar
Jan Möbius committed
551
552

      connect( coreWidget_->examiner_widgets_[i], SIGNAL( viewUpdated() ),
553
               this, SLOT( viewUpdated()) ,Qt::DirectConnection);
554

555
      connect( coreWidget_->examiner_widgets_[i], SIGNAL( viewChanged() ),
556
               coreWidget_->examiner_widgets_[i], SLOT( updateGL() ) ,Qt::DirectConnection);
557

Jan Möbius's avatar
Jan Möbius committed
558
559
560
      // Set post processor
      PostProcessorDialog::loadSavedPostProcessors(i);

561
562
563
564
565
      // ====================================================
      // Set renderer
      // ====================================================

      QString defaultRendererKey  = "Viewer" + QString::number(i)+"/DefaultRenderer";
566
      QString defaultRendererName = OpenFlipperSettings().value(defaultRendererKey,"Default Classical Renderer Plugin").toString();
567
568
569
570
571
572
573
574

      // Check if the renderer is there
      int defaultRendererId = renderManager().getRendererId(defaultRendererName);

      if ( defaultRendererId == -1 ) {
        emit log(LOGERR,tr("Stored default renderer \"") + defaultRendererName + tr("\" is not available, trying Classical!"));

        // Check if the renderer is there
575
        defaultRendererId = renderManager().getRendererId("Default Classical Renderer Plugin");
576
577
578
579
580
581

        // Classical available?
        if ( defaultRendererId != -1 ) {
          renderManager().setActive(defaultRendererId,i);
        } else {
          emit log(LOGERR,tr("Default classical renderer is also not available. Trying to use any other renderer i can find!"));
582
583
584
585
586
587

          // debug information for this case, print renderer count and their names
          const unsigned int rendererCount = renderManager().available();
          emit log(LOGERR,tr("Currently ") + QString::number(rendererCount) + tr(" renderers are available:") );
          for (unsigned int i = 0 ; i < rendererCount ; ++i )
            emit log(LOGERR, tr("Renderer ") + QString::number(i) + ": " + renderManager()[i]->name );
588
589
590
591
592
593
594
595
596
597
        }

      } else {
        renderManager().setActive(defaultRendererId,i);
      }

    }

    // Warn the user in the log and via messagebox, that he is using the build in renderer only
    if ( renderManager().available() == 1 ) {
598
      finishSplash();
599
600
601
602
      emit log(LOGERR,tr("No external plugin renderers available!"));
      emit log(LOGERR,tr("The build in renderer is only a very limited one and is missing many features!"));
      emit log(LOGERR,tr("You should build and use the other renderers!"));

Isaak Lim's avatar
Isaak Lim committed
603
      StaysOnTopMessageBox::warning(0,tr( "No external plugin renderers available!"),tr("The build in renderer is only a very limited one and is missing many features.\nYou should build and use the other free renderers shipped with OpenFlipper."));
Jan Möbius's avatar
Jan Möbius committed
604
    }
605

Jan Möbius's avatar
 
Jan Möbius committed
606
  }
607

Jan Möbius's avatar
Jan Möbius committed
608
609
610
611
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================

Jan Möbius's avatar
 
Jan Möbius committed
612
613
  QStringList optionFiles = OpenFlipper::Options::optionFiles();
  for ( int i = 0 ; i < (int)optionFiles.size(); ++i) {
614

615
    if (splash_) {
616
      splash_->showMessage(tr("Loading Configuration File %1/%2").arg(i+1).arg(optionFiles.size()),
Jan Möbius's avatar
 
Jan Möbius committed
617
618
                           Qt::AlignBottom | Qt::AlignLeft , Qt::white);
    }
619

Jan Möbius's avatar
Jan Möbius committed
620
621
    // Load global ini files. Use only plugin global options from these files as the
    // rest has been loaded at the beginning.
622
623
624
    if ( OpenFlipper::Options::gui() )
      coreWidget_->updateRecent();

Jan Möbius's avatar
Jan Möbius committed
625
    openIniFile( optionFiles[i] ,false,true,false);
Jan Möbius's avatar
 
Jan Möbius committed
626
627
  }

628
  if (splash_)
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
629
      splash_->clearMessage();
630

Jan Möbius's avatar
Jan Möbius committed
631
632
633
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================
634

Jan Möbius's avatar
 
Jan Möbius committed
635
  if ( OpenFlipper::Options::lang().contains("UTF") || OpenFlipper::Options::lang().contains("utf") ) {
636
    emit log(LOGWARN,tr("UTF8-Locale used!"));
Jan Möbius's avatar
Jan Möbius committed
637
638
639
640
//     emit log(LOGWARN,"Only OFF files are fully supported with UTF8. Others might fail.");
//     emit log(LOGWARN,"You can change your locale by :");
//     emit log(LOGWARN,"export LANG=C");
//     emit log(LOGWARN,"Work is in progress to resolve this issue.");
641
  }
Jan Möbius's avatar
 
Jan Möbius committed
642
643

  if ( OpenFlipper::Options::gui() ) {
Dirk Wilden's avatar
Dirk Wilden committed
644

645
    QFile statesFile(OpenFlipper::Options::configDirStr()  + OpenFlipper::Options::dirSeparator() + "WindowStates.dat");
Dirk Wilden's avatar
Dirk Wilden committed
646

647
648
    if (statesFile.exists() ) {
      QSettings windowStates(OpenFlipper::Options::configDirStr()  + OpenFlipper::Options::dirSeparator() + "WindowStates.dat", QSettings::IniFormat);
649

650
651
652
653
      //try to restore the windowState
      coreWidget_->restoreState (windowStates.value("Core/Window/State").toByteArray ());
      //try to restore the geometry
      coreWidget_->restoreGeometry (windowStates.value("Core/Window/Geometry").toByteArray ());
Dirk Wilden's avatar
Dirk Wilden committed
654

655
656
      coreWidget_->toolSplitter_->restoreState (windowStates.value("Core/ToolSplitter").toByteArray ());
      coreWidget_->splitter_->restoreState (windowStates.value("Core/LogSplitter").toByteArray ());
657

658
      coreWidget_->show();
659

660
661
662
663
664
665
666
667
668
      applyOptions();

      windowStates.beginGroup ("Core");
      windowStates.beginGroup ("LogSlider");
      coreWidget_->slidingLogger_->restoreState (windowStates);
      windowStates.endGroup ();
      coreWidget_->toolBox_->restoreState (windowStates);
      windowStates.endGroup ();

669
670
671
672
673

      // Restore if window was maximized or not
      if ( windowStates.value("Core/Window/WindowState",false).toBool() )
        coreWidget_->setWindowState( coreWidget_->windowState() | Qt::WindowMaximized  );

674
675
676
    } else {

      coreWidget_->show();
677

678
679
680
      applyOptions();

    }
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
681

682
    if ( splash_ ) {
Jan Möbius's avatar
Jan Möbius committed
683
        splash_->raise();
684
        splash_->showMessage(tr("Ready."), Qt::AlignBottom | Qt::AlignLeft , Qt::white);
685
        finishSplash();
Jan Möbius's avatar
 
Jan Möbius committed
686
    }
687

688
    // start checking for scenegraph changes
689
    scenegraphCheckTimer_->setInterval (1000 / OpenFlipperSettings().value("Core/Gui/glViewer/maxFrameRate",35).toInt() );
690
    scenegraphCheckTimer_->start ();
Jan Möbius's avatar
 
Jan Möbius committed
691
  }
692

693
694
695
  // System is ready now.
  OpenFlipper::Options::finishedStartup();
  
Jan Möbius's avatar
Jan Möbius committed
696
  QTimer::singleShot(100, this, SLOT(slotExecuteAfterStartup()));
Jan Möbius's avatar
 
Jan Möbius committed
697
698
}

699

Jan Möbius's avatar
 
Jan Möbius committed
700
701
702
703
//-----------------------------------------------------------------------------

Core::~Core()
{
704

705
706
707
708
709
  // Delete the objectRoot if it was constructed
  if ( objectRoot_ != 0 ) {
    objectRoot_->deleteSubtree();
    delete objectRoot_;
  }
710

Jan Möbius's avatar
 
Jan Möbius committed
711
  // Clean up loggers
712
713
714
  for ( uint i = 0 ; i < loggers_.size(); ++i )
    delete loggers_[i];

Jan Möbius's avatar
Jan Möbius committed
715
  delete coreWidget_;
Jan Möbius's avatar
 
Jan Möbius committed
716
717
718
719
}

//-----------------------------------------------------------------------------

720
721
722
723
724
725
std::vector<PluginInfo>& Core::plugins()  {
  return PluginStorage::plugins();
};

//-----------------------------------------------------------------------------

Jan Möbius's avatar
 
Jan Möbius committed
726
727
728
void
Core::slotMouseEventIdentify( QMouseEvent* _event )
{
Dirk Wilden's avatar
Dirk Wilden committed
729
730
731
//   // Dont do anything as a context Menu will popup on right button click
//   if ( _event->button() == Qt::RightButton )
//     return;
732

733
734
735
  // Only catch left-button clicks
  if(_event->button() != Qt::LeftButton) return;

Jan Möbius's avatar
Jan Möbius committed
736
737
738
739
740
741
742
743
744
  const QObject* senderPointer = sender();
  unsigned int examinerId = 0;

  if ( senderPointer == 0 ) {
    std::cerr << "Error : slotMouseEventIdentify directly called! This should only be called by an examiner" << std::endl;
  } else {
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i ) {
      if ( senderPointer == coreWidget_->examiner_widgets_[i] ) {
        examinerId = i;
745
        if ( OpenFlipper::Options::doSlotDebugging() )
746
              emit log(LOGINFO,tr("slotMouseEventIdentify from examiner ") + QString::number(i) );
Jan Möbius's avatar
Jan Möbius committed
747
748
749
750
751
752
753
754
        break;
      }
    }

  }

  PluginFunctions::setActiveExaminer( examinerId );

755
  // Do picking
756
  size_t   node_idx, target_idx;
757
758
759
  ACG::Vec3d     hit_point;

  if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx, target_idx, &hit_point)) {