Core.cc 80.3 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
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69





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


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

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

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

Jan Möbius's avatar
Jan Möbius committed
70
71
72
73
74
#if QT_VERSION >= 0x050000
#else
 #undef QT_NO_OPENGL
 #include <QGLFormat>
#endif
Jan Möbius's avatar
 
Jan Möbius committed
75
76
77
78
79
80
81
82
83
84

#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
85
#include "OpenFlipper/BasePlugin/PluginFunctionsCore.hh"
Jan Möbius's avatar
 
Jan Möbius committed
86

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

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

91
92
#include <OpenFlipper/common/BaseObjectCore.hh>
#include <OpenFlipper/common/TypesInternal.hh>
Jan Möbius's avatar
Jan Möbius committed
93

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

Jan Möbius's avatar
 
Jan Möbius committed
96
97
98
#define WIDGET_HEIGHT 800
#define WIDGET_WIDTH  800

99
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
100

101
102
103
namespace {
    void recreateContext()
    {
104
#ifdef WIN32
105
106
107
108
109
110
        QOpenGLContext* ctx = QOpenGLContext::currentContext();
        QSurfaceFormat format = QSurfaceFormat::defaultFormat();
        ctx->setFormat(format);
        ctx->create();
        QOffscreenSurface* surface = new QOffscreenSurface();
        ctx->makeCurrent(surface);
111
#endif
112
113
114
    }
}

Jan Möbius's avatar
 
Jan Möbius committed
115
/** \brief Constuctor for the Core Widget ( This is stage 1 , call init for stage 2)
116
 *
Jan Möbius's avatar
 
Jan Möbius committed
117
118
119
120
121
122
123
124
125
 * 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(),
126
  capture_(false),
127
  processManager_(0),
Jan Möbius's avatar
 
Jan Möbius committed
128
  nextBackupId_(0),
Dirk Wilden's avatar
Dirk Wilden committed
129
  nextBackupGroupId_(0),
130
  objectRoot_(0),
131
132
  coreWidget_(0),
  splash_(0)
Jan Möbius's avatar
 
Jan Möbius committed
133
{
134

Dirk Wilden's avatar
Dirk Wilden committed
135
136
137
138
  //init logFile
  logStream_ = 0;
  logFile_ = 0;

Dirk Wilden's avatar
Dirk Wilden committed
139
140
  //init nodes
  root_node_scenegraph_ = new ACG::SceneGraph::SeparatorNode(0, "SceneGraph Root Node");
Jan Möbius's avatar
Jan Möbius committed
141
  
142
  // init global data node
Jan Möbius's avatar
Jan Möbius committed
143
  root_node_scenegraph_global_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_ , "SceneGraph Rendered Root Node");
144
  
Jan Möbius's avatar
Jan Möbius committed
145
  // This separator will manage the cores nodes
146
  core_nodes_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Core Nodes");
Jan Möbius's avatar
Jan Möbius committed
147
148
149
150
  
  // 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
151
  coordsysNode_->setTraverseMode (BaseNode::NodeFirst | BaseNode::SecondPass);
Jan Möbius's avatar
Jan Möbius committed
152
  
Jan Möbius's avatar
Jan Möbius committed
153
  // Separator handling the nodes for data
154
  dataSeparatorNode_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Data Separator Root Node");
Jan Möbius's avatar
Jan Möbius committed
155
  
Jan Möbius's avatar
Jan Möbius committed
156
  // Separator handling the nodes for data
Jan Möbius's avatar
Jan Möbius committed
157
  dataRootNode_      = new ACG::SceneGraph::SeparatorNode(dataSeparatorNode_, "Data Root Node");
Dirk Wilden's avatar
Dirk Wilden committed
158

Jan Möbius's avatar
 
Jan Möbius committed
159
160
161
   // Add ViewMode All
  ViewMode* vm = new ViewMode();
  vm->name = "All";
Jan Möbius's avatar
Jan Möbius committed
162
  vm->icon = "viewmode_all.png";
Jan Möbius's avatar
 
Jan Möbius committed
163
  vm->custom = false;
Jan Möbius's avatar
Jan Möbius committed
164
  vm->visibleToolboxes = QStringList();
165

Jan Möbius's avatar
 
Jan Möbius committed
166
167
  viewModes_.push_front(vm);

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

171
  for (int i=0; i < 4; i++) {
172
    Viewer::ViewerProperties* viewerProperty = new Viewer::ViewerProperties(i);
173
174
175
    viewerProperty->snapshotBaseFileName("snap-Viewer-" + QString::number(i) + ".png");
    viewerProperties.push_back( viewerProperty );
  }
Dirk Wilden's avatar
Dirk Wilden committed
176
177
178

  PluginFunctions::setViewerProperties(viewerProperties);

179
180
181
182
183
184
  //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
185
186
  // Get all relevant Paths and Options from option files
  setupOptions();
Jan Möbius's avatar
Jan Möbius committed
187

188
189
  // set discriptions for scriptable slots
  setDescriptions();
190
191
192
  
  // Initialize the build in dataTypes
  initializeTypes();
Dirk Wilden's avatar
Dirk Wilden committed
193
194
195
  
  // Initialize the build in updateTypes
  initializeUpdateTypes();
Jan Möbius's avatar
 
Jan Möbius committed
196
197
}

198
199
200
/** \brief Second initialization stage
 *
 * This Stage does the following :\n
Jan Möbius's avatar
 
Jan Möbius committed
201
202
203
204
205
206
 * - 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
 */
207
208
void
Core::init() {
Jan Möbius's avatar
Jan Möbius committed
209
210
211
  
  // Check library versions
  checkLibraryVersions();
212

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

216
  // Topmost node of the scenegraph
Jan Möbius's avatar
   
Jan Möbius committed
217
  PluginFunctions::setSceneGraphRootNode( root_node_scenegraph_ );
218
219
220
221
  
  // 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
222

Jan Möbius's avatar
 
Jan Möbius committed
223
  // Initialize the first object as the root Object for the object tree
224
  objectRoot_ =  dynamic_cast< BaseObject* > ( new GroupObject("ObjectRoot") );
Jan Möbius's avatar
 
Jan Möbius committed
225
  PluginFunctions::setDataRoot( objectRoot_ );
Jan Möbius's avatar
Jan Möbius committed
226
227
228
  
  // Bring up the object manager ( has to be done after the rootobject is created)
  connect(getObjectManager(),SIGNAL(newObject(int)), this ,SLOT(newObject(int)));
229
230
  
  connect(getObjectManager(),SIGNAL(deletedObject(int)), this ,SLOT(deletedObject(int)));
231

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

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

239
240
241
242
243
244
245
246
    // 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 ();
247

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

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

254
      splash_->showMessage(tr("Initializing mainwindow") ,
Jan Möbius's avatar
 
Jan Möbius committed
255
256
                          Qt::AlignBottom | Qt::AlignLeft , Qt::white);
    }
257

Jan Möbius's avatar
Jan Möbius committed
258
    coreWidget_ = new CoreWidget(viewModes_ , plugins_, coreSlots_);
259

260
261
262
263
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxScrollArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolbox());

Jan Möbius's avatar
 
Jan Möbius committed
264
    connect(coreWidget_, SIGNAL(clearAll())           , this, SLOT(clearAll()));
265
    connect(coreWidget_, SIGNAL(loadMenu())           , this, SLOT(loadObject()));
Jan Möbius's avatar
 
Jan Möbius committed
266
    connect(coreWidget_, SIGNAL(addEmptyObjectMenu()) , this, SLOT(slotAddEmptyObjectMenu()));
267
268
269
270
    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()));
271
    connect(coreWidget_, SIGNAL(applyOptions())       , this, SLOT(applyOptions()));
Dirk Wilden's avatar
Dirk Wilden committed
272
    connect(coreWidget_, SIGNAL(saveOptions())        , this, SLOT(saveOptions()));
Jan Möbius's avatar
 
Jan Möbius committed
273
274
    connect(coreWidget_, SIGNAL(recentOpen(QAction*)) , this, SLOT(slotRecentOpen(QAction*)));
    connect(coreWidget_, SIGNAL(exit())               , this, SLOT(slotExit()));
275

276
277
278

    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
279
280
    connect( coreWidget_, SIGNAL( stopVideoCapture() ), this, SLOT( stopVideoCapture() ) );
    connect( coreWidget_, SIGNAL( startVideoCapture(QString,int,bool) ), this, SLOT( startVideoCapture(QString,int,bool) ) );
281
    connect( coreWidget_, SIGNAL( dragOpenFile(QString)), this, SLOT(loadObject(QString)));
282

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

Dirk Wilden's avatar
Dirk Wilden committed
285
    connect(coreWidget_, SIGNAL(call(QString,bool&)), this, SLOT(slotCall(QString,bool&)));
286
287
    
    connect( coreWidget_->logWidget_->openMeshFilterAction_,SIGNAL(toggled(bool)), this, SLOT(enableOpenMeshErrorLog(bool)) );
Dirk Wilden's avatar
Dirk Wilden committed
288

Jan Möbius's avatar
Jan Möbius committed
289
290
291
292
293
294
295
296
297
298
299
300
    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
301
302
303
#ifdef ARCH_DARWIN
    width = rect.width() - 300;
    height = rect.height() - 150;
Jan Möbius's avatar
Jan Möbius committed
304

Jan Möbius's avatar
Jan Möbius committed
305
//     coreWidget_->setMaximumSize( width, height  );
Jan Möbius's avatar
Jan Möbius committed
306
307
#endif

Jan Möbius's avatar
Jan Möbius committed
308
    coreWidget_->resize(width,height);
309

Dirk Wilden's avatar
Dirk Wilden committed
310
311
312
313
314
    #ifdef DEBUG
      coreWidget_->setWindowTitle( OpenFlipper::Options::windowTitle() + " [DEBUG]" );
    #else
      coreWidget_->setWindowTitle( OpenFlipper::Options::windowTitle() );
    #endif
315

Jan Möbius's avatar
Jan Möbius committed
316
317
318
    // Sanity check for OpenGL capabilities!
    checkOpenGLCapabilities();

Jan Möbius's avatar
 
Jan Möbius committed
319
  }
320

Jan Möbius's avatar
 
Jan Möbius committed
321
322
323
324
  // ======================================================================
  // Create intermediate logger class for Core which will mangle the output
  // ======================================================================
  PluginLogger* newlog = new PluginLogger("Core");
325

Jan Möbius's avatar
 
Jan Möbius committed
326
327
  loggers_.push_back(newlog);
  connect(this,SIGNAL(log(Logtype, QString )),newlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
328
329
  connect(this,SIGNAL(log(QString )),newlog,SLOT(slotLog(QString )),Qt::DirectConnection);

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

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

Dirk Wilden's avatar
Dirk Wilden committed
336
337
  // connection to file logger
  connect(newlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
338
339
340
341
342
343
344

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

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

Dirk Wilden's avatar
Dirk Wilden committed
346
347
    loggers_.push_back(widgetlog);
    connect(coreWidget_,SIGNAL(log(Logtype, QString )),widgetlog,SLOT(slotLog(Logtype, QString )),Qt::DirectConnection);
348
349
    connect(coreWidget_,SIGNAL(log(QString )),widgetlog,SLOT(slotLog(QString )),Qt::DirectConnection);

Dirk Wilden's avatar
Dirk Wilden committed
350
351
352
    // 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
353
354
    // connection to file logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
355
  }
356

Jan Möbius's avatar
 
Jan Möbius committed
357
358
359
360
361
362
  // ======================================================================
  // Catch OpenMesh Error logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGERR);
  omerr().connect(*newlog);
  omerr().disconnect(std::cerr);
363

Jan Möbius's avatar
 
Jan Möbius committed
364
  loggers_.push_back(newlog);
365

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

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

Jan Möbius's avatar
 
Jan Möbius committed
374
375
376
377
378
379
  // ======================================================================
  // Catch OpenMesh omout logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGINFO);
  omout().connect(*newlog);
  omout().disconnect(std::cout);
380

Jan Möbius's avatar
 
Jan Möbius committed
381
  loggers_.push_back(newlog);
382

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

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

Jan Möbius's avatar
 
Jan Möbius committed
391
392
393
394
395
  // ======================================================================
  // Catch OpenMesh omlog logs with an own Logger
  // ======================================================================
  newlog = new PluginLogger("Core ( OpenMesh )",LOGOUT);
  omlog().connect(*newlog);
396

Jan Möbius's avatar
 
Jan Möbius committed
397
  loggers_.push_back(newlog);
398

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

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

Jan Möbius's avatar
 
Jan Möbius committed
407
408
409
410
  // ======================================================================
  // Log Scripting stuff through a separate logger
  // ======================================================================
  newlog = new PluginLogger("Scripting",LOGOUT);
411

Jan Möbius's avatar
 
Jan Möbius committed
412
  loggers_.push_back(newlog);
413

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

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

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

425
  
Jan Möbius's avatar
 
Jan Möbius committed
426
  // ======================================================================
427
  // Set up QtScript Environment
Jan Möbius's avatar
 
Jan Möbius committed
428
  // ======================================================================
429
  
Jan Möbius's avatar
Jan Möbius committed
430
431
432
  // Set a reference to the scriptengine for simple rpc calls
  RPC::setScriptEngine(&scriptEngine_);

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

Jan Möbius's avatar
 
Jan Möbius committed
435
436
  // process Events every 500 msecs during script execution
  scriptEngine_.setProcessEventsInterval( 500 );
437

Jan Möbius's avatar
 
Jan Möbius committed
438
439
440
441
  // Register own print function :
  QScriptValue printFunction = scriptEngine_.newFunction(myPrintFunction);
  printFunction.setProperty("textedit",scriptEngine_.newQObject(this));
  scriptEngine_.globalObject().setProperty("print", printFunction);
442

443
444
445
  // Register print to file function :
  QScriptValue printToFileFunc = scriptEngine_.newFunction(printToFileFunction);
  scriptEngine_.globalObject().setProperty("printToFile", printToFileFunc);
446
  scriptingFunctions_.push_back( "-.printToFile(QString,QString)" );
447

Jan Möbius's avatar
Jan Möbius committed
448
449
450
451
452
453
  // Register help function :
  QScriptValue helpFunc = scriptEngine_.newFunction(helpFunction);
  helpFunc.setProperty("core",scriptEngine_.newQObject(this));
  scriptEngine_.globalObject().setProperty("help", helpFunc);
  scriptingFunctions_.push_back( "-.help(QString)" );

454
455
456
457
458
459
460
461
462
  // 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 )
  //==========================================================================
463
464
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueVector,
Jan Möbius's avatar
 
Jan Möbius committed
465
466
                          fromScriptValueVector,
                          scriptEngine_.newQObject(&vec3dPrototype_));
467
                          
Jan Möbius's avatar
 
Jan Möbius committed
468
  // set a constructor to allow creation via Vector(x,y,z)
Jan Möbius's avatar
Jan Möbius committed
469
470
471
472
473
474
475
  QScriptValue ctorVec3 = scriptEngine_.newFunction(createVector);
  scriptEngine_.globalObject().setProperty("Vector", ctorVec3);

  //==========================================================================
  // Register the 4d Vector Type to the core ( is Vec4d )
  //==========================================================================
  qScriptRegisterMetaType(&scriptEngine_,
476
477
                          toScriptValueVector4,
                          fromScriptValueVector4,
Jan Möbius's avatar
Jan Möbius committed
478
479
480
481
482
                          scriptEngine_.newQObject(&vec4dPrototype_));

  // set a constructor to allow creation via Vector(x,y,z)
  QScriptValue ctorVec4 = scriptEngine_.newFunction(createVector4);
  scriptEngine_.globalObject().setProperty("Vector4", ctorVec4);
483
484
485
486
                          
  //==========================================================================
  // Register the DataType Class to the core
  //==========================================================================
487

488
  // Register DataType in QScriptEngine
489
  qScriptRegisterMetaType<DataType>(&scriptEngine_,
490
491
492
493
494
                          toScriptValueDataType,
                          fromScriptValueDataType,
                          scriptEngine_.newQObject(&DataTypePrototype_));
                          
  // set a constructor to allow creation via DataType(uint)
495
496
497
498
499
500
  QScriptValue dataTypector = scriptEngine_.newFunction(createDataType);
  scriptEngine_.globalObject().setProperty("DataType", dataTypector);     
  
  //==========================================================================
  // Register the Matrix Class to the core
  //==========================================================================
501

Jan Möbius's avatar
 
Jan Möbius committed
502
  // Register Matrix Type to scripting Engine ( is ACG::Matrix4x4d )
503
504
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueMatrix4x4 ,
Jan Möbius's avatar
 
Jan Möbius committed
505
506
                          fromScriptValueMatrix4x4,
                          scriptEngine_.newQObject(&matrix4x4Prototype_));
507

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

512
513
514
515
  //==========================================================================
  //  Collect Core scripting information
  //==========================================================================

Jan Möbius's avatar
 
Jan Möbius committed
516
517
518
519
520
521
  QScriptValue scriptInstance = scriptEngine_.newQObject(this,
                                                         QScriptEngine::QtOwnership,
                                                         QScriptEngine::ExcludeChildObjects |
                                                         QScriptEngine::ExcludeSuperClassMethods |
                                                         QScriptEngine::ExcludeSuperClassProperties
                                                         );
522

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

Jan Möbius's avatar
 
Jan Möbius committed
525
526
527
  QScriptValueIterator it(scriptInstance);
  while (it.hasNext()) {
    it.next();
528

Jan Möbius's avatar
 
Jan Möbius committed
529
    /// Skip all signals for function calls
530
    if ( checkSignal( this, it.name().toLatin1() ) )
Jan Möbius's avatar
 
Jan Möbius committed
531
      continue;
532

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

Jan Möbius's avatar
 
Jan Möbius committed
535
  }
536

Jan Möbius's avatar
 
Jan Möbius committed
537
  loadPlugins();
538

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

Dirk Wilden's avatar
Dirk Wilden committed
541
542
543
    //register keyBinding for all scripting slots
    coreWidget_->slotRegisterSlotKeyBindings();

544
545
546
    //get keyAssignments from config files
    restoreKeyBindings();

Jan Möbius's avatar
Marlin:    
Jan Möbius committed
547
548
    if ( OpenFlipper::Options::currentViewMode( ) != "" )
      coreWidget_->setViewMode( OpenFlipper::Options::currentViewMode() );
Jan Möbius's avatar
 
Jan Möbius committed
549
550
    else
      coreWidget_->setViewMode("All");
551

552
    // Set the renderer to the one stored in the settings or to default
553
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i ) {
Jan Möbius's avatar
Jan Möbius committed
554
555
556
557
      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
558
559
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalMouseEventLight(QMouseEvent*)),
              this                              , SLOT(slotMouseEventLight(QMouseEvent*)));
Jan Möbius's avatar
Jan Möbius committed
560
561
      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
562
563

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

566
      connect( coreWidget_->examiner_widgets_[i], SIGNAL( viewChanged() ),
567
               coreWidget_->examiner_widgets_[i], SLOT( updateGL() ) ,Qt::DirectConnection);
568

Jan Möbius's avatar
Jan Möbius committed
569
570
571
      // Set post processor
      PostProcessorDialog::loadSavedPostProcessors(i);

572
573
574
575
576
      // ====================================================
      // Set renderer
      // ====================================================

      QString defaultRendererKey  = "Viewer" + QString::number(i)+"/DefaultRenderer";
577
      QString defaultRendererName = OpenFlipperSettings().value(defaultRendererKey,"Default Classical Renderer Plugin").toString();
578
579
580
581
582
583
584
585

      // 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
586
        defaultRendererId = renderManager().getRendererId("Default Classical Renderer Plugin");
587
588
589
590
591
592

        // 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!"));
593
594
595
596
597
598

          // 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 );
599
600
601
602
603
604
605
606
607
608
        }

      } 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 ) {
609
      finishSplash();
610
611
612
613
      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
614
      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
615
    }
616

Jan Möbius's avatar
 
Jan Möbius committed
617
  }
618

Jan Möbius's avatar
Jan Möbius committed
619
620
621
622
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================

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

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

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

Jan Möbius's avatar
Jan Möbius committed
636
    openIniFile( optionFiles[i] ,false,true,false);
Jan Möbius's avatar
 
Jan Möbius committed
637
638
  }

639
  if (splash_)
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
640
      splash_->clearMessage();
641

Jan Möbius's avatar
Jan Möbius committed
642
643
644
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================
645

Jan Möbius's avatar
 
Jan Möbius committed
646
  if ( OpenFlipper::Options::lang().contains("UTF") || OpenFlipper::Options::lang().contains("utf") ) {
647
    emit log(LOGWARN,tr("UTF8-Locale used!"));
Jan Möbius's avatar
Jan Möbius committed
648
649
650
651
//     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.");
652
  }
Jan Möbius's avatar
 
Jan Möbius committed
653
654

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

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

658
659
    if (statesFile.exists() ) {
      QSettings windowStates(OpenFlipper::Options::configDirStr()  + OpenFlipper::Options::dirSeparator() + "WindowStates.dat", QSettings::IniFormat);
660

661
662
663
664
      //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
665

666
667
      coreWidget_->toolSplitter_->restoreState (windowStates.value("Core/ToolSplitter").toByteArray ());
      coreWidget_->splitter_->restoreState (windowStates.value("Core/LogSplitter").toByteArray ());
668

669
      coreWidget_->show();
670
      recreateContext();
671

672
673
674
675
676
677
678
679
680
      applyOptions();

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

681
682
683
684
685

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

686
687
688
    } else {

      coreWidget_->show();
689
690
      recreateContext();

691
692
693
      applyOptions();

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

695
    if ( splash_ ) {
Jan Möbius's avatar
Jan Möbius committed
696
        splash_->raise();
697
        splash_->showMessage(tr("Ready."), Qt::AlignBottom | Qt::AlignLeft , Qt::white);
698
        finishSplash();
Jan Möbius's avatar
 
Jan Möbius committed
699
    }
700

701
    // start checking for scenegraph changes
702
    scenegraphCheckTimer_->setInterval (1000 / OpenFlipperSettings().value("Core/Gui/glViewer/maxFrameRate",35).toInt() );
703
    scenegraphCheckTimer_->start ();
Jan Möbius's avatar
 
Jan Möbius committed
704
  }
705

706
707
708
  // System is ready now.
  OpenFlipper::Options::finishedStartup();
  
Jan Möbius's avatar
Jan Möbius committed
709
  QTimer::singleShot(100, this, SLOT(slotExecuteAfterStartup()));
Jan Möbius's avatar
 
Jan Möbius committed
710
711
}

712

Jan Möbius's avatar
 
Jan Möbius committed
713
714
715
716
//-----------------------------------------------------------------------------

Core::~Core()
{
717

718
719
720
721
722
  // Delete the objectRoot if it was constructed
  if ( objectRoot_ != 0 ) {
    objectRoot_->deleteSubtree();
    delete objectRoot_;
  }
723

Jan Möbius's avatar
 
Jan Möbius committed
724
  // Clean up loggers
725
726
727
  for ( uint i = 0 ; i < loggers_.size(); ++i )
    delete loggers_[i];

Jan Möbius's avatar
Jan Möbius committed
728
  delete coreWidget_;
Jan Möbius's avatar
 
Jan Möbius committed
729
730
731
732
733
734
735
}

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

void
Core::slotMouseEventIdentify( QMouseEvent* _event )
{
Dirk Wilden's avatar
Dirk Wilden committed
736
737
738
//   // Dont do anything as a context Menu will popup on right button click
//   if ( _event->button() == Qt::RightButton )
//     return;
739

740
741
742
  // Only catch left-button clicks
  if(_event->button() != Qt::LeftButton) return;

Jan Möbius's avatar
Jan Möbius committed
743
744
745
746
747
748
749
750
751
  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;
752
        if ( OpenFlipper::Options::doSlotDebugging() )
753
              emit log(LOGINFO,tr("slotMouseEventIdentify from examiner ") + QString::number(i) );
Jan Möbius's avatar
Jan Möbius committed
754
755
756
757
758
759
760
761
        break;
      }
    }

  }

  PluginFunctions::setActiveExaminer( examinerId );

762
  // Do picking
763
  size_t   node_idx, target_idx;