Core.cc 79.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
*                                                                            *
*   $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

/** \brief Constuctor for the Core Widget ( This is stage 1 , call init for stage 2)
102
 *
Jan Möbius's avatar
 
Jan Möbius committed
103
104
105
106
107
108
109
110
111
 * 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(),
112
  capture_(false),
113
  processManager_(0),
Jan Möbius's avatar
 
Jan Möbius committed
114
  nextBackupId_(0),
Dirk Wilden's avatar
Dirk Wilden committed
115
  nextBackupGroupId_(0),
116
  objectRoot_(0),
117
118
  coreWidget_(0),
  splash_(0)
Jan Möbius's avatar
 
Jan Möbius committed
119
{
120

Dirk Wilden's avatar
Dirk Wilden committed
121
122
123
124
  //init logFile
  logStream_ = 0;
  logFile_ = 0;

Dirk Wilden's avatar
Dirk Wilden committed
125
126
  //init nodes
  root_node_scenegraph_ = new ACG::SceneGraph::SeparatorNode(0, "SceneGraph Root Node");
Jan Möbius's avatar
Jan Möbius committed
127
  
128
  // init global data node
Jan Möbius's avatar
Jan Möbius committed
129
  root_node_scenegraph_global_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_ , "SceneGraph Rendered Root Node");
130
  
Jan Möbius's avatar
Jan Möbius committed
131
  // This separator will manage the cores nodes
132
  core_nodes_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Core Nodes");
Jan Möbius's avatar
Jan Möbius committed
133
134
135
136
  
  // 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
137
  coordsysNode_->setTraverseMode (BaseNode::NodeFirst | BaseNode::SecondPass);
Jan Möbius's avatar
Jan Möbius committed
138
  
Jan Möbius's avatar
Jan Möbius committed
139
  // Separator handling the nodes for data
140
  dataSeparatorNode_ = new ACG::SceneGraph::SeparatorNode(root_node_scenegraph_global_, "Data Separator Root Node");
Jan Möbius's avatar
Jan Möbius committed
141
  
Jan Möbius's avatar
Jan Möbius committed
142
  // Separator handling the nodes for data
Jan Möbius's avatar
Jan Möbius committed
143
  dataRootNode_      = new ACG::SceneGraph::SeparatorNode(dataSeparatorNode_, "Data Root Node");
Dirk Wilden's avatar
Dirk Wilden committed
144

Jan Möbius's avatar
 
Jan Möbius committed
145
146
147
   // Add ViewMode All
  ViewMode* vm = new ViewMode();
  vm->name = "All";
Jan Möbius's avatar
Jan Möbius committed
148
  vm->icon = "viewmode_all.png";
Jan Möbius's avatar
 
Jan Möbius committed
149
  vm->custom = false;
Jan Möbius's avatar
Jan Möbius committed
150
  vm->visibleToolboxes = QStringList();
151

Jan Möbius's avatar
 
Jan Möbius committed
152
153
  viewModes_.push_front(vm);

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

157
  for (int i=0; i < 4; i++) {
158
    Viewer::ViewerProperties* viewerProperty = new Viewer::ViewerProperties(i);
159
160
161
    viewerProperty->snapshotBaseFileName("snap-Viewer-" + QString::number(i) + ".png");
    viewerProperties.push_back( viewerProperty );
  }
Dirk Wilden's avatar
Dirk Wilden committed
162
163
164

  PluginFunctions::setViewerProperties(viewerProperties);

165
166
167
168
169
170
  //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
171
172
  // Get all relevant Paths and Options from option files
  setupOptions();
Jan Möbius's avatar
Jan Möbius committed
173

174
175
  // set discriptions for scriptable slots
  setDescriptions();
176
177
178
  
  // Initialize the build in dataTypes
  initializeTypes();
Dirk Wilden's avatar
Dirk Wilden committed
179
180
181
  
  // Initialize the build in updateTypes
  initializeUpdateTypes();
Jan Möbius's avatar
 
Jan Möbius committed
182
183
}

184
185
186
/** \brief Second initialization stage
 *
 * This Stage does the following :\n
Jan Möbius's avatar
 
Jan Möbius committed
187
188
189
190
191
192
 * - 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
 */
193
194
void
Core::init() {
Jan Möbius's avatar
Jan Möbius committed
195
196
197
  
  // Check library versions
  checkLibraryVersions();
198

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

202
  // Topmost node of the scenegraph
Jan Möbius's avatar
   
Jan Möbius committed
203
  PluginFunctions::setSceneGraphRootNode( root_node_scenegraph_ );
204
205
206
207
  
  // 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
208

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

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

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

225
226
227
228
229
230
231
232
    // 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 ();
233

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

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

240
      splash_->showMessage(tr("Initializing mainwindow") ,
Jan Möbius's avatar
 
Jan Möbius committed
241
242
                          Qt::AlignBottom | Qt::AlignLeft , Qt::white);
    }
243

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

246
247
248
249
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxScrollArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolboxArea());
    spinBoxEventFilter_.registerScrollArea(coreWidget_->getToolbox());

Jan Möbius's avatar
 
Jan Möbius committed
250
    connect(coreWidget_, SIGNAL(clearAll())           , this, SLOT(clearAll()));
251
    connect(coreWidget_, SIGNAL(loadMenu())           , this, SLOT(loadObject()));
Jan Möbius's avatar
 
Jan Möbius committed
252
    connect(coreWidget_, SIGNAL(addEmptyObjectMenu()) , this, SLOT(slotAddEmptyObjectMenu()));
253
254
255
256
    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()));
257
    connect(coreWidget_, SIGNAL(applyOptions())       , this, SLOT(applyOptions()));
Dirk Wilden's avatar
Dirk Wilden committed
258
    connect(coreWidget_, SIGNAL(saveOptions())        , this, SLOT(saveOptions()));
Jan Möbius's avatar
 
Jan Möbius committed
259
260
    connect(coreWidget_, SIGNAL(recentOpen(QAction*)) , this, SLOT(slotRecentOpen(QAction*)));
    connect(coreWidget_, SIGNAL(exit())               , this, SLOT(slotExit()));
261

262
263
264

    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
265
266
    connect( coreWidget_, SIGNAL( stopVideoCapture() ), this, SLOT( stopVideoCapture() ) );
    connect( coreWidget_, SIGNAL( startVideoCapture(QString,int,bool) ), this, SLOT( startVideoCapture(QString,int,bool) ) );
267
    connect( coreWidget_, SIGNAL( dragOpenFile(QString)), this, SLOT(loadObject(QString)));
268

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

Dirk Wilden's avatar
Dirk Wilden committed
271
    connect(coreWidget_, SIGNAL(call(QString,bool&)), this, SLOT(slotCall(QString,bool&)));
272
273
    
    connect( coreWidget_->logWidget_->openMeshFilterAction_,SIGNAL(toggled(bool)), this, SLOT(enableOpenMeshErrorLog(bool)) );
Dirk Wilden's avatar
Dirk Wilden committed
274

Jan Möbius's avatar
Jan Möbius committed
275
276
277
278
279
280
281
282
283
284
285
286
    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
287
288
289
#ifdef ARCH_DARWIN
    width = rect.width() - 300;
    height = rect.height() - 150;
Jan Möbius's avatar
Jan Möbius committed
290

Jan Möbius's avatar
Jan Möbius committed
291
//     coreWidget_->setMaximumSize( width, height  );
Jan Möbius's avatar
Jan Möbius committed
292
293
#endif

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

Dirk Wilden's avatar
Dirk Wilden committed
296
297
298
299
300
    #ifdef DEBUG
      coreWidget_->setWindowTitle( OpenFlipper::Options::windowTitle() + " [DEBUG]" );
    #else
      coreWidget_->setWindowTitle( OpenFlipper::Options::windowTitle() );
    #endif
301

Jan Möbius's avatar
Jan Möbius committed
302
303
304
    // Sanity check for OpenGL capabilities!
    checkOpenGLCapabilities();

Jan Möbius's avatar
 
Jan Möbius committed
305
  }
306

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

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

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

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

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
336
337
338
    // 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
339
340
    // connection to file logger
    connect(widgetlog,SIGNAL(log(Logtype, QString )),this,SLOT(slotLogToFile(Logtype, QString )),Qt::DirectConnection);
Dirk Wilden's avatar
Dirk Wilden committed
341
  }
342

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

Jan Möbius's avatar
 
Jan Möbius committed
350
  loggers_.push_back(newlog);
351

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
367
  loggers_.push_back(newlog);
368

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
383
  loggers_.push_back(newlog);
384

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

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

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

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

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

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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
421
422
  // process Events every 500 msecs during script execution
  scriptEngine_.setProcessEventsInterval( 500 );
423

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

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

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

440
441
442
443
444
445
446
447
448
  // 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 )
  //==========================================================================
449
450
  qScriptRegisterMetaType(&scriptEngine_,
                          toScriptValueVector,
Jan Möbius's avatar
 
Jan Möbius committed
451
452
                          fromScriptValueVector,
                          scriptEngine_.newQObject(&vec3dPrototype_));
453
                          
Jan Möbius's avatar
 
Jan Möbius committed
454
  // set a constructor to allow creation via Vector(x,y,z)
Jan Möbius's avatar
Jan Möbius committed
455
456
457
458
459
460
461
  QScriptValue ctorVec3 = scriptEngine_.newFunction(createVector);
  scriptEngine_.globalObject().setProperty("Vector", ctorVec3);

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

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

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

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

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

498
499
500
501
  //==========================================================================
  //  Collect Core scripting information
  //==========================================================================

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

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

Jan Möbius's avatar
 
Jan Möbius committed
511
512
513
  QScriptValueIterator it(scriptInstance);
  while (it.hasNext()) {
    it.next();
514

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

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

Jan Möbius's avatar
 
Jan Möbius committed
521
  }
522

Jan Möbius's avatar
 
Jan Möbius committed
523
  loadPlugins();
524

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

Dirk Wilden's avatar
Dirk Wilden committed
527
528
529
    //register keyBinding for all scripting slots
    coreWidget_->slotRegisterSlotKeyBindings();

530
531
532
    //get keyAssignments from config files
    restoreKeyBindings();

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

538
    // Set the renderer to the one stored in the settings or to default
539
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i ) {
Jan Möbius's avatar
Jan Möbius committed
540
541
542
543
      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
544
545
      connect( coreWidget_->examiner_widgets_[i], SIGNAL(signalMouseEventLight(QMouseEvent*)),
              this                              , SLOT(slotMouseEventLight(QMouseEvent*)));
Jan Möbius's avatar
Jan Möbius committed
546
547
      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
548
549

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

552
      connect( coreWidget_->examiner_widgets_[i], SIGNAL( viewChanged() ),
553
               coreWidget_->examiner_widgets_[i], SLOT( updateGL() ) ,Qt::DirectConnection);
554

Jan Möbius's avatar
Jan Möbius committed
555
556
557
      // Set post processor
      PostProcessorDialog::loadSavedPostProcessors(i);

558
559
560
561
562
      // ====================================================
      // Set renderer
      // ====================================================

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

      // 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
572
        defaultRendererId = renderManager().getRendererId("Default Classical Renderer Plugin");
573
574
575
576
577
578

        // 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!"));
579
580
581
582
583
584

          // 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 );
585
586
587
588
589
590
591
592
593
594
        }

      } 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 ) {
595
      finishSplash();
596
597
598
599
      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
600
      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
601
    }
602

Jan Möbius's avatar
 
Jan Möbius committed
603
  }
604

Jan Möbius's avatar
Jan Möbius committed
605
606
607
608
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================

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

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

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

Jan Möbius's avatar
Jan Möbius committed
622
    openIniFile( optionFiles[i] ,false,true,false);
Jan Möbius's avatar
 
Jan Möbius committed
623
624
  }

625
  if (splash_)
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
626
      splash_->clearMessage();
627

Jan Möbius's avatar
Jan Möbius committed
628
629
630
  // ===============================================================================================
  // Load Settings from configuration files
  // ===============================================================================================
631

Jan Möbius's avatar
 
Jan Möbius committed
632
  if ( OpenFlipper::Options::lang().contains("UTF") || OpenFlipper::Options::lang().contains("utf") ) {
633
    emit log(LOGWARN,tr("UTF8-Locale used!"));
Jan Möbius's avatar
Jan Möbius committed
634
635
636
637
//     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.");
638
  }
Jan Möbius's avatar
 
Jan Möbius committed
639
640

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

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

644
645
    if (statesFile.exists() ) {
      QSettings windowStates(OpenFlipper::Options::configDirStr()  + OpenFlipper::Options::dirSeparator() + "WindowStates.dat", QSettings::IniFormat);
646

647
648
649
650
      //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
651

652
653
      coreWidget_->toolSplitter_->restoreState (windowStates.value("Core/ToolSplitter").toByteArray ());
      coreWidget_->splitter_->restoreState (windowStates.value("Core/LogSplitter").toByteArray ());
654

655
      coreWidget_->show();
656

657
658
659
660
661
662
663
664
665
      applyOptions();

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

666
667
668
669
670

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

671
672
673
    } else {

      coreWidget_->show();
674

675
676
677
      applyOptions();

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

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

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

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

696

Jan Möbius's avatar
 
Jan Möbius committed
697
698
699
700
//-----------------------------------------------------------------------------

Core::~Core()
{
701

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

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

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

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

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

724
725
726
  // Only catch left-button clicks
  if(_event->button() != Qt::LeftButton) return;

Jan Möbius's avatar
Jan Möbius committed
727
728
729
730
731
732
733
734
735
  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;
736
        if ( OpenFlipper::Options::doSlotDebugging() )
737
              emit log(LOGINFO,tr("slotMouseEventIdentify from examiner ") + QString::number(i) );
Jan Möbius's avatar
Jan Möbius committed
738
739
740
741
742
743
744
745
        break;
      }
    }

  }

  PluginFunctions::setActiveExaminer( examinerId );

746
  // Do picking
747
  size_t   node_idx, target_idx;
748
749
750
  ACG::Vec3d     hit_point;

  if(PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING, _event->pos(), node_idx, target_idx, &hit_point)) {
Jan Möbius's avatar
Jan Möbius committed
751

752
    BaseObjectData* object = 0;
Jan Möbius's avatar
Jan Möbius committed
753

754
755
756
757
758
759
760
761
    if(PluginFunctions::getPickedObject(node_idx, object)) {
      // Request type information widget
      InformationInterface* infoPlugin = 0;
      infoPlugin = getInfoPlugin(object->dataType());
      if(infoPlugin != 0)
          infoPlugin->slotInformationRequested(_event->pos(), object->dataType());
    }
  }
Jan Möbius's avatar
 
Jan Möbius committed
762
763
764
}

//-----------------------------------------------------------------------------
Jan Möbius's avatar
Mike:    
Jan Möbius committed
765
766
767
768
769
770
771
772
773