Developer Documentation

openFunctions.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44
45
46
47
48 #include "Core.hh"
49
50 #include <ACG/QtWidgets/QtFileDialog.hh>
51 #include <ACG/Scenegraph/SceneGraphAnalysis.hh>
52
53 #include <OpenFlipper/common/RecentFiles.hh>
54
55 #include "OpenFlipper/widgets/loadWidget/loadWidget.hh"
56 #include "OpenFlipper/widgets/addEmptyWidget/addEmptyWidget.hh"
57
58 #include "OpenFunctionThread.hh"
59
60 #include <ACG/Scenegraph/SeparatorNode.hh>
61
62 void Core::resetScenegraph( bool _resetTrackBall ) {
63
64 if ( OpenFlipper::Options::gui() && !OpenFlipper::Options::sceneGraphUpdatesBlocked() ) {
65
66 unsigned int maxPases = 1;
67 ACG::Vec3d bbmin,bbmax;
68 ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);
69
70 for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
71 // update scene graph (get new bounding box and set projection right, including near and far plane)
72 PluginFunctions::viewerProperties(i).lockUpdate();
73 coreWidget_->examiner_widgets_[i]->sceneGraph(root_node_scenegraph_,maxPases,bbmin,bbmax, _resetTrackBall );
74 PluginFunctions::viewerProperties(i).unLockUpdate();
75 coreWidget_->examiner_widgets_[i]->updateGL();
76 }
77
78 }
79
80 }
81
82 //========================================================================================
83 // === Open/Add-Empty Functions ============================
84 //========================================================================================
85
86
87
88 void Core::slotGetAllFilters ( QStringList& _list){
90 // Iterate over all types
91 for (int i=0; i < (int)supportedTypes().size(); i++){
92 QString f = supportedTypes()[i].plugin->getLoadFilters();
93 f = f.section(")",0,0).section("(",1,1).trimmed();
94 _list << f;
95 }
96 }
97
98 void Core::commandLineOpen(const QString& _filename, bool _asPolyMesh ){
99
100 QString file = _filename;
101
102 // Modify filename to contain full paths if they were given as relative paths
103 if ( !file.startsWith("/") && !file.contains(":") ) {
104 file = QDir::currentPath();
105 file += OpenFlipper::Options::dirSeparator();
106 file += _filename;
107 }
108
109 // Add to the open list
110 commandLineFileNames_.push_back(std::pair< QString , bool >(file, _asPolyMesh));
111 }
112
113 void Core::commandLineScript(const QString& _filename ) {
114
115 QString file = _filename;
116
117 // Modify filename to contain full paths if they were given as relative paths
118 if ( !file.startsWith("/") && !file.contains(":") ) {
119 file = QDir::currentPath();
120 file += OpenFlipper::Options::dirSeparator();
121 file += _filename;
122 }
123
124 // Add to the open list
125 commandLineScriptNames_.push_back(file);
126 }
127
128 void Core::slotExecuteAfterStartup() {
129
130
131 // Update logger
132 if ( OpenFlipper::Options::gui())
133 coreWidget_->updateInSceneLoggerGeometry();
134
135 //check if we have scripting support:
136 bool scriptingSupport = false;
137 slotPluginExists("scripting",scriptingSupport);
138 if ( ! scriptingSupport ) {
139 emit log(LOGERR ,tr("No scripting support available, please check if we load a scripting plugin .. Skipping script execution on startup"));
140 }
141
142 // Collect all script files from the scripting subdirectory and execute them if possible.
143 // You can use this directory to execute scipts that modify for example modify the ui at
144 // every startup.
145 if ( scriptingSupport ) {
146
147 // Get the files in the directory
148 QDir scriptDir = OpenFlipper::Options::scriptDir();
149 QStringList scriptFiles = scriptDir.entryList(QDir::Files,QDir::Name);
150
151 // Execute all files ending with ofs
152 for ( int i = 0 ; i < scriptFiles.size(); ++i ) {
153 if ( scriptFiles[i].endsWith("ofs",Qt::CaseInsensitive) )
154 emit executeFileScript(scriptDir.path() + "/" + scriptFiles[i]);
155
156 if ( scriptFiles[i].endsWith("ofp",Qt::CaseInsensitive) )
157 executePythonScriptFile(scriptDir.path() + "/" + scriptFiles[i]);
158 }
159
160 // Clear scripting window afterexecuting the coresubdir scripts
161 bool ok = false;
162 slotCall( "scripting" ,"clearEditor()",ok);
163 }
164
165 OpenFlipper::Options::blockSceneGraphUpdates();
166
167 // Open all files given at the commandline
168 for ( uint i = 0 ; i < commandLineFileNames_.size() ; ++i ) {
169
170 // Skip scripts here as they will be handled by a different function
171 QString tmp = commandLineFileNames_[i].first;
172 if ( tmp.endsWith(".ofs",Qt::CaseInsensitive) || tmp.endsWith(".ofp",Qt::CaseInsensitive) ) {
173 commandLineScriptNames_.push_back(commandLineFileNames_[i].first);
174 continue;
175 }
176
177 // If the file was given with the polymesh option, open them as polymeshes.
178 if (commandLineFileNames_[i].second)
179 loadObject(typeId("PolyMesh"), commandLineFileNames_[i].first);
180 else {
181 loadObject(commandLineFileNames_[i].first);
182 }
183 }
184
185 OpenFlipper::Options::unblockSceneGraphUpdates();
186
187 // Reset the scenegraph once to make sure everything is fine
188 resetScenegraph( true );
189
190 // If we have scripting support, execute the scripts given at the commandline.
191 if ( scriptingSupport )
192 for ( unsigned int i = 0 ; i < commandLineScriptNames_.size() ; ++i ) {
193
194 if ( commandLineScriptNames_[i].endsWith("ofs",Qt::CaseInsensitive) )
195 emit executeFileScript(commandLineScriptNames_[i]);
196
197 if ( commandLineScriptNames_[i].endsWith("ofp",Qt::CaseInsensitive) )
198 executePythonScriptFile(commandLineScriptNames_[i]);
199
200 }
201
202 // If we don't have a gui and we are not under remote control,
203 // exit the application as there would be no way to execute further commands
204 if ( !OpenFlipper::Options::gui() && !OpenFlipper::Options::remoteControl())
205 exitApplication();
206 }
207
208 void Core::loadObjectFinished(QString _threadId)
209 {
210 if ( OpenFlipper::Options::gui() ) {
211 LoadFromPluginThread* thread = dynamic_cast<LoadFromPluginThread*>(sender());
212 if (!thread)
213 return;
214
215 int id = thread->getObjId(0);
216 QString filename = thread->getFilename(0);
217
218 if ( id != -1 ) {
219 coreWidget_->statusMessage( tr("Loading %1 ... done").arg(filename), 4000 );
220
221 // Get the object to figure out the data type
222 BaseObject* object;
223 PluginFunctions::getObject(id,object);
224
225 // Security check, if object really exists
226 if ( object != 0 ) {
227
228 // Add to recent files with the given datatype
229 if ( OpenFlipper::Options::gui() )
230 coreWidget_->addRecent(filename, object->dataType());
231 } else {
232 emit log(LOGERR, tr("Unable to add recent as object with id %1 could not be found!").arg(id) );
233 }
234
235 } else
236 coreWidget_->statusMessage( tr("Loading %1 ... failed!").arg(filename), 4000 );
237
238 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
239 coreWidget_->setStatus(ApplicationStatus::READY );
240 }
241
242 }
243
244
245 int Core::loadObject ( QString _filename ) {
252 if (_filename.endsWith(".ini",Qt::CaseInsensitive)) {
253
254 // Load all information from the given ini file
255 openIniFile(_filename,true,true,true);
256
257 if ( OpenFlipper::Options::gui() )
258 coreWidget_->addRecent(_filename, DATA_UNKNOWN);
259
260 return -2;
261 } else if (_filename.endsWith(".ofs",Qt::CaseInsensitive)) {
262 emit log(LOGINFO ,tr("Starting script execution of OpenFlipper Script %1.").arg( _filename)) ;
263 emit executeFileScript(_filename);
264 } else if (_filename.endsWith(".ofp",Qt::CaseInsensitive)) {
265 emit log(LOGINFO ,tr("Starting script execution of Python script %1.").arg( _filename)) ;
266 executePythonScriptFile(_filename);
267 } else {
268
269 QFileInfo fi(_filename);
270
271 for (int i=0; i < (int)supportedTypes().size(); i++){
272
273 QString filters = supportedTypes()[i].loadFilters;
274
275 // Only take the parts inside the brackets
276 filters = filters.section("(",1).section(")",0,0);
277
278 // Split into blocks
279 QStringList separateFilters = filters.split(" ");
280
281 bool found = false;
282
283 // for all filters associated with this plugin
284 for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
285 separateFilters[filterId] = separateFilters[filterId].trimmed();
286
287 //check extension
288 if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
289 found = true;
290 break;
291 }
292
293 if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
294 found = true;
295 emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
296 break;
297 }
298
299 }
300
301 // continue processing only if found
302 if ( ! found )
303 continue;
304
305 if ( OpenFlipper::Options::gui() ) {
306 coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
307 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
308 coreWidget_->setStatus(ApplicationStatus::PROCESSING );
309 }
310
311 QString jobId = QString("Loading_"+_filename);
312 QVector<LoadFromPluginThread::LoadInfos> infos;
313 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
314 LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
315
316 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
317 connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
318
319 if ( OpenFlipper::Options::gui() )
320 {
321 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
322
323 slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
324 thread->start();
325 thread->startProcessing();
326
327
328 while(thread->isRunning())
329 QApplication::processEvents();
330 // process last events
331 QApplication::processEvents();
332 }
333 else
334 {
335 thread->loadFromPlugin();
336 }
337
338 int objId = thread->getObjId(0);
339
340 return objId;
341 }
342 }
343
344 emit log(LOGERR, tr("Unable to load object (type unknown). No suitable plugin found!") );
345
346 return -1;
347 }
348
349
351 int Core::loadObject( DataType _type, QString _filename) {
356 if (_type == DATA_UNKNOWN)
357 return loadObject(_filename);
358
359 QFileInfo fi(_filename);
360
361 std::vector<int> typeIds;
362 for (int i=0; i < (int)supportedTypes().size(); i++) {
363 if (supportedTypes()[i].type & _type || supportedTypes()[i].type == _type) {
364
365 QString filters = supportedTypes()[i].loadFilters;
366
367 // Only take the parts inside the brackets
368 filters = filters.section("(",1).section(")",0,0);
369
370 // Split into blocks
371 QStringList separateFilters = filters.split(" ");
372
373 // for all filters associated with this plugin
374 for ( int filterId = 0 ; filterId < separateFilters.size(); ++filterId ) {
375 separateFilters[filterId] = separateFilters[filterId].trimmed();
376
377 //check extension
378 if ( separateFilters[filterId].endsWith( "*." + fi.completeSuffix() , Qt::CaseInsensitive) ) {
379 typeIds.push_back(i);
380 continue;
381 }
382
383 if ( separateFilters[filterId].endsWith( "*." + fi.suffix() , Qt::CaseInsensitive) ) {
384 typeIds.push_back(i);
385 emit log(LOGWARN,"Found supported datatype but only the suffix is matched not the complete suffix!");
386 continue;
387 }
388 }
389 }
390 }
391
392 // load file with plugins
393 size_t nPlugins = typeIds.size();
394 if (nPlugins > 0) {
395
396 int i = -1;
397
398 // several plugins can load this type
399 if (nPlugins > 1) {
400 // let the user choose the plugin for loading
401 if ( OpenFlipper::Options::gui() ) {
402 QStringList items;
403 for (size_t j = 0; j < nPlugins; ++j) {
404 // only add the plugin name if it does not already exist in the itemlist
405 if (items.indexOf(supportedTypes()[typeIds[j]].name) == -1)
406 items << supportedTypes()[typeIds[j]].name;
407 }
408
409 bool ok;
410 QString item = QInputDialog::getItem(coreWidget_, tr("File Plugins"),
411 tr("Please choose a plugin for loading:"), items, 0, false, &ok);
412 if (!ok) {
413 emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
414 return -1; //no plugin found
415 } else
416 i = typeIds[items.indexOf(item)];
417 }
418 // if there is no gui just take the first one for now
419 else {
420 i = 0;
421 }
422 } else
423 i = typeIds[0];
424
425 if ( OpenFlipper::Options::gui() ) {
426 coreWidget_->statusMessage( tr("Loading %1 ... ").arg(_filename));
427 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
428 coreWidget_->setStatus(ApplicationStatus::PROCESSING );
429 }
430
431 //load file
432 QString jobId = QString("Loading_"+_filename);
433 QVector<LoadFromPluginThread::LoadInfos> infos;
434
435 if ( checkSlot( supportedTypes()[i].object , "loadObject(QString,DataType)" ) )
436 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _type,_filename));
437 else
438 infos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[i].plugin, _filename));
439
440 LoadFromPluginThread* thread = new LoadFromPluginThread(infos, jobId);
441
442 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
443 connect(thread, SIGNAL(finished(QString)), this, SLOT(loadObjectFinished(QString)));
444
445 if ( OpenFlipper::Options::gui() )
446 {
447 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
448
449 slotStartJob(jobId , QString("Loading %1").arg(_filename) , 0, 0, true);
450 thread->start();
451 thread->startProcessing();
452
453
454 while(thread->isRunning())
455 QApplication::processEvents();
456 // process last events
457 QApplication::processEvents();
458 }
459 else
460 {
461 thread->loadFromPlugin();
462 }
463
464 int objId = thread->getObjId(0);
465
466 return objId;
467
468 } else {
469
470 emit log(LOGERR, tr("Unable to load object. No suitable plugin found!") );
471
472 return -1; //no plugin found
473 }
474 }
475
476
477 int Core::addEmptyObject( DataType _type ) {
478 // Iterate over all plugins. The first plugin supporting the addEmpty function for the
479 // specified type will be used to create the new object. If adding the object failed,
480 // we iterate over the remaining plugins.
481
482 // Iterate over type plugins
483 for (int i=0; i < (int)supportedDataTypes_.size(); i++)
484 if ( supportedDataTypes_[i].type & _type ) {
485 int retCode = supportedDataTypes_[i].plugin->addEmpty();
486 if ( retCode != -1 )
487 return retCode;
488 }
489
490 return -1; // no plugin found
491 }
492
493 //========================================================================================
494 // === Open/Add-Empty Slots ============================
495 //========================================================================================
496
497 void Core::slotAddEmptyObject( DataType _type, int* _id)
498 {
499 slotAddEmptyObject(_type,*_id);
500 }
501
502 void Core::slotAddEmptyObject( DataType _type , int& _id ) {
503
504
505 if (QThread::currentThread() != QApplication::instance()->thread())
506 {
507 //execute method in main thread
508 QMetaObject::invokeMethod(this,"slotAddEmptyObject",Qt::BlockingQueuedConnection, Q_ARG(DataType, _type), Q_ARG(int*, &_id));
509 }
510 else
511 {
512 _id = addEmptyObject( _type );
513 if ( OpenFlipper::Options::doSlotDebugging() ) {
514 if ( sender() != 0 ) {
515 if ( sender()->metaObject() != 0 ) {
516 emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by ") +
517 QString( sender()->metaObject()->className() ) );
518 }
519 } else {
520 emit log(LOGINFO,"slotAddEmptyObject( " + _type.name() + "," + QString::number(_id) + tr(" ) called by Core") );
521 }
522 }
523 }
524 }
525
527 void Core::slotCopyObject( int _oldId , int& _newId ) {
528
529 if ( _oldId == -1 ) {
530 emit log(LOGERR,tr("Requested copy for illegal Object id: %1").arg(_oldId) );
531 _newId = -1;
532 return;
533 }
534
535 // get the node
536 BaseObject* object = objectRoot_->childExists(_oldId);
537
538 if ( !object ) {
539 emit log(LOGERR,tr("Requested copy for unknown Object id: %1 ").arg(_oldId) );
540 _newId = -1;
541 return ;
542 }
543
544 // Copy the item
545 BaseObject* copy = object->copy();
546
547 if ( copy == 0 ) {
548 emit log(LOGERR,tr("Unable to create a copy of the object."));
549 return;
550 }
551
552 // Integrate into object tree
553 copy->setParent( object->parent() );
554
555 // return the new id
556 _newId = copy->id();
557
558 // tell plugins that a new object has been created
559 slotEmptyObjectAdded(_newId);
560
561 // tell plugins that the object has been updated
562 slotObjectUpdated(_newId);
563
564 }
565
566
568 void Core::slotLoad(QStringList _filenames, IdList _pluginIDs) {
569
570
571 QString filemsg = "";
572 if (_filenames.size() > 1)
573 filemsg = QString( tr("Loading Files ...") );
574 else
575 filemsg = QString( tr("Loading %1 ...").arg(_filenames[0]) );
576
577 if ( OpenFlipper::Options::gui() ) {
578 coreWidget_->statusMessage( filemsg );
579 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
580 coreWidget_->setStatus(ApplicationStatus::PROCESSING );
581 }
582
583 //setup thread
584 QString jobId = QString("Loading File");
585 if (_filenames.size() > 1)
586 jobId += "s";
587
588 QVector<LoadFromPluginThread::LoadInfos> loadInfos;
589 for (int i = 0; i < _filenames.size(); ++i)
590 loadInfos.push_back(LoadFromPluginThread::LoadInfos(supportedTypes()[_pluginIDs[i]].plugin, _filenames[i]));
591 LoadFromPluginThread* thread = new LoadFromPluginThread(loadInfos, jobId);
592
593 connect(thread, SIGNAL(finished(QString)), this, SLOT(slotFinishJob(QString)));
594 connect(thread, SIGNAL(state(QString , int )), this, SLOT(slotSetJobState(QString , int)));
595
596 if ( OpenFlipper::Options::gui() )
597 {
598 connect(thread, SIGNAL(updateView()), this, SLOT(updateView()), Qt::BlockingQueuedConnection);
599 //block log (decrease performance when loading multiple files)
600 coreWidget_->logWidget_->setUpdatesEnabled(false);
601
602 // start thread
603 if (_filenames.size() > 1)
604 slotStartJob(jobId , QString(filemsg), 0, _filenames.size(), true);
605 else
606 slotStartJob(jobId , QString(filemsg), 0, 0, true);
607
608 thread->start();
609 thread->startProcessing();
610
611 //wait thread
612 while(thread->isRunning())
613 QApplication::processEvents();
614 //process last occuring events
615 QApplication::processEvents();
616
617 //unblock and update log
618 coreWidget_->logWidget_->setUpdatesEnabled(true);
619 }
620 else
621 {
622 thread->loadFromPlugin();
623 }
624
625 // Initialize as unknown type
626 QVector<DataType> type = QVector<DataType>(_filenames.size(), DATA_UNKNOWN);
627
628 for (int i = 0; i < _filenames.size(); ++i)
629 {
630 int id = thread->getObjId(i);
631
632 if ( OpenFlipper::Options::gui() ) {
633
634 if ( id != -1 )
635 coreWidget_->statusMessage( tr("Loading %1 done").arg(_filenames[i]), 4000 );
636 else
637 coreWidget_->statusMessage( tr("Loading %1 failed").arg(_filenames[i]), 4000 );
638
639 if ( !OpenFlipper::Options::sceneGraphUpdatesBlocked() )
640 coreWidget_->setStatus(ApplicationStatus::READY );
641 }
642
643 if ( id > 0 ) {
644
645 BaseObjectData* object;
646 PluginFunctions::getObject(id,object);
647
648 if ( !object ) {
649
650 BaseObject* baseObj = 0;
651 GroupObject* group = 0;
652
653 PluginFunctions::getObject(id,baseObj);
654
655 if (baseObj){
656
657 group = dynamic_cast< GroupObject* > (baseObj);
658
659 if (group)
660 type[i] = DATA_GROUP;
661
662 }
663
664 if ( group == 0 ){
665 emit log(LOGERR,tr("Object id returned but no object with this id has been found! Error in one of the file plugins!"));
666 return;
667 }
668 }
669
670 // Get the objects type
671 if (object)
672 type[i] = object->dataType();
673 }
674 }
675
676 // If the id was greater than zero, add the file to the recent files.
677 if ( OpenFlipper::Options::gui() )
678 for (int i = 0; i < _filenames.size(); ++i)
679 if ( thread->getObjId(i) >= 0 )
680 coreWidget_->addRecent(_filenames[i], type[i]);
681
682 }
683
685 void Core::slotLoad(QString _filename, DataType _type, int& _id) {
686 _id = loadObject(_type,_filename);
687
688 if ( _id < 0 )
689 _id = -1;
690 else
691 if ( OpenFlipper::Options::gui() )
692 coreWidget_->addRecent(_filename,_type);
693 }
694
696 void Core::slotFileOpened ( int _id ) {
697
698 if (QThread::currentThread() != QApplication::instance()->thread())
699 {
700 QMetaObject::invokeMethod(this,"slotFileOpened",Qt::QueuedConnection, Q_ARG(int, _id));
701 return;
702 }
703
704 if ( OpenFlipper::Options::doSlotDebugging() ) {
705 if ( sender() != 0 ) {
706 if ( sender()->metaObject() != 0 ) {
707 emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by ") +
708 QString( sender()->metaObject()->className() ) );
709 }
710 } else {
711 emit log(LOGINFO,tr("slotObjectOpened( ") + QString::number(_id) + tr(" ) called by Core") );
712 }
713 }
714
715 // get the opened object
716 BaseObjectData* object;
717 PluginFunctions::getObject(_id,object);
718
719 // ================================================================================
720 // Recompute bounding box and scenegraph info
721 // Reset scene center here to include new object
722 // ================================================================================
723 resetScenegraph(true);
724
725 // ================================================================================
726 // Tell plugins, that a file has been opened
727 // ================================================================================
728 emit openedFile( _id );
729
730 // ================================================================================
731 // Print Info to logger
732 // ================================================================================
733 emit log( LOGINFO ,object->getObjectinfo() );
734
735 // ================================================================================
736 // Tell plugins, that the Object is updated and the active object has changed
737 // ================================================================================
738 emit signalObjectUpdated(_id );
739 emit signalObjectUpdated(_id, UPDATE_ALL);
740
741 // ================================================================================
742 // Create initial backup
743 // ================================================================================
744 emit createBackup(_id,"Original Object");
745
746 // ================================================================================
747 // Add the file to the recent files menu
748 // ================================================================================
749 QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
750 BaseObject* object2;
751 PluginFunctions::getObject(_id,object2);
752
753 // ================================================================================
754 // show all files
755 // ================================================================================
756 PluginFunctions::viewAll();
757
758 // objectRoot_->dumpTree();
759 }
760
762 void Core::slotEmptyObjectAdded ( int _id ) {
763
764 if ( OpenFlipper::Options::doSlotDebugging() ) {
765 if ( sender() != 0 ) {
766 if ( sender()->metaObject() != 0 ) {
767 emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by ") +
768 QString( sender()->metaObject()->className() ) );
769 }
770 } else {
771 emit log(LOGINFO,tr("slotEmptyObjectAdded( ") + QString::number(_id) + tr(" ) called by Core") );
772 }
773 }
774
775 // get the opened object
776 BaseObjectData* object;
777 PluginFunctions::getObject(_id,object);
778
779
780 emit emptyObjectAdded( _id );
781
782 // Tell the Plugins that the Object List and the active object have changed
783 emit signalObjectUpdated(_id);
784 emit signalObjectUpdated(_id,UPDATE_ALL);
785
786 resetScenegraph(false);
787
789 // QString filename = object->path() + OpenFlipper::Options::dirSeparator() + object->name();
790
791 // addRecent(filename);
792 }
793
794 //========================================================================================
795 // === Menu Slots ============================
796 //========================================================================================
797
799 void Core::slotAddEmptyObjectMenu() {
800 std::vector< DataType > types;
801 QStringList typeNames;
802
803 DataType currentType = 2;
804
805 // Iterate over all Types known to the core
806 // Start at 2:
807 // 0 type is defined as DATA_UNKNOWN
808 // 1 type is defined as DATA_GROUP
809 // Therefore we have two types less then reported
810 //
811 for ( uint i = 0 ; i < typeCount() - 2 ; ++i) {
812
813 // Iterate over all supported types (created from plugins on load)
814 // Check if a plugin supports addEmpty for the current type.
815 // Only if the type is supported, add it to the addEmpty Dialog
816
817 // typePlugin
818 for ( uint j = 0 ; j < supportedDataTypes_.size(); j++) {
819
820 // Check if a plugin supports the current type
821 if ( supportedDataTypes_[j].type & currentType ) {
822 types.push_back(currentType);
823 typeNames.push_back( typeName( currentType ) );
824
825 // Stop here as we need only one plugin supporting addEmpty for a given type
826 break;
827 }
828 }
829
830 // filePlugin
831 for ( uint j = 0 ; j < supportedTypes().size(); j++) {
832
833 // Check if a plugin supports the current Type
834 if ( supportedTypes()[j].type & currentType ) {
835
836 // Avoid duplicates
837 bool duplicate = false;
838 for(std::vector< DataType >::iterator it = types.begin(); it != types.end(); ++it) {
839 if(*it == currentType) {
840 duplicate = true;
841 break;
842 }
843 }
844
845 if(!duplicate) {
846 types.push_back(currentType);
847 typeNames.push_back( typeName( currentType ) );
848
849 // Stop here as we need only one plugin supporting addEmpty for a given type
850 break;
851 }
852 }
853 }
854
855 // Advance to next type ( Indices are bits so multiply by two to get next bit)
856 ++currentType;
857 }
858
859
860
861 if (supportedTypes().size() != 0) {
862
863 static addEmptyWidget* widget = 0;
864
865 if ( !widget ){
866 widget = new addEmptyWidget(types,typeNames);
867 widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
868 connect(widget,SIGNAL(chosen(DataType, int&)),this,SLOT(slotAddEmptyObject(DataType, int&)));
869 }
870
871 widget->show();
872
873 } else
874 emit log(LOGERR,tr("Could not show 'add Empty' dialog. Missing file-plugins ?"));
875
876 }
877
878 //========================================================================================
879 // === Public Slots ============================
880 //========================================================================================
881
883 void Core::loadObject() {
884
885 if ( OpenFlipper::Options::gui() ){
886
887 if (supportedTypes().size() != 0){
888 LoadWidget* widget = new LoadWidget(supportedTypes());
889 connect(widget,SIGNAL(loadFiles(QStringList, IdList)),this,SLOT(slotLoad(QStringList, IdList)));
890 connect(widget,SIGNAL(save(int, QString, int)),this,SLOT(saveObject(int, QString, int)));
891
892 widget->setWindowIcon( OpenFlipper::Options::OpenFlipperIcon() );
893
894 widget->showLoad();
895
896 widget->disconnect();
897 delete widget;
898
899 }else
900 emit log(LOGERR,tr("Could not show 'load objects' dialog. Missing file-plugins."));
901
902 }
903 }
904
906 void Core::loadSettings(){
907
908 if ( OpenFlipper::Options::gui() ){
909
910 QString complete_name;
911
912
913 QFileDialog fileDialog( coreWidget_,
914 tr("Load Settings"),
915 OpenFlipperSettings().value("Core/CurrentDir").toString(),
916 tr("INI files (*.ini)") );
917
918 fileDialog.setOption (QFileDialog::DontUseNativeDialog, true);
919 fileDialog.setAcceptMode ( QFileDialog::AcceptOpen );
920 fileDialog.setFileMode ( QFileDialog::AnyFile );
921
922 QGridLayout *layout = (QGridLayout*)fileDialog.layout();
923
924 QGroupBox* optionsBox = new QGroupBox( &fileDialog ) ;
925 optionsBox->setSizePolicy( QSizePolicy ( QSizePolicy::Expanding , QSizePolicy::Preferred ) );
926 optionsBox->setTitle(tr("Options"));
927 layout->addWidget( optionsBox, layout->rowCount() , 0 , 1,layout->columnCount() );
928
929 QCheckBox *loadProgramSettings = new QCheckBox(optionsBox);
930 loadProgramSettings->setText(tr("Load program settings"));
931 loadProgramSettings->setToolTip(tr("Load all current program settings from the file ( This will include view settings, colors,...) "));
932 loadProgramSettings->setCheckState( Qt::Unchecked );
933
934 QCheckBox *loadPluginSettings = new QCheckBox(optionsBox);
935 loadPluginSettings->setText(tr("Load per Plugin Settings"));
936 loadPluginSettings->setToolTip(tr("Plugins should load their current global settings from the file"));
937 loadPluginSettings->setCheckState( Qt::Checked );
938
939 QCheckBox *loadObjectInfo = new QCheckBox(optionsBox);
940 loadObjectInfo->setText(tr("Load all objects defined in the file"));
941 loadObjectInfo->setToolTip(tr("Load all objects which are defined in the file"));
942 loadObjectInfo->setCheckState( Qt::Checked );
943
944 QBoxLayout* frameLayout = new QBoxLayout(QBoxLayout::TopToBottom,optionsBox);
945 frameLayout->addWidget( loadProgramSettings , 0 , 0);
946 frameLayout->addWidget( loadPluginSettings , 1 , 0);
947 frameLayout->addWidget( loadObjectInfo , 2 , 0);
948 frameLayout->addStretch();
949
950 fileDialog.resize(550 ,500);
951
952 // ========================================================================================
953 // show the saveSettings-Dialog and get the target file
954 // ========================================================================================
955 QStringList fileNames;
956 if (fileDialog.exec()) {
957 fileNames = fileDialog.selectedFiles();
958 } else {
959 return;
960 }
961
962 if ( fileNames.size() > 1 ) {
963 std::cerr << "Too many save filenames selected" << std::endl;
964 return;
965 }
966
967 complete_name = fileNames[0];
968
969
970 QString newpath = complete_name.section(OpenFlipper::Options::dirSeparator(),0,-2);
971 OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
972
973 if ( complete_name.endsWith("ini",Qt::CaseInsensitive) ) {
974 openIniFile( complete_name,
975 loadProgramSettings->isChecked(),
976 loadPluginSettings->isChecked(),
977 loadObjectInfo->isChecked());
978 if ( loadProgramSettings->isChecked() )
979 applyOptions();
980 }
981
982 coreWidget_->addRecent(complete_name, DATA_UNKNOWN);
983 }
984 }
985
987 void Core::loadSettings(QString _filename){
988
989 if ( !QFile(_filename).exists() )
990 return;
991
992 QString newpath = _filename.section(OpenFlipper::Options::dirSeparator(),0,-2);
993 OpenFlipperSettings().setValue("Core/CurrentDir", newpath);
994
995 if ( _filename.endsWith("obj",Qt::CaseInsensitive) ) {
996 loadObject(_filename);
997 applyOptions();
998 } else {
999 // Loaded function for recent files. Load everything.
1000 openIniFile(_filename,true,true,true);
1001 applyOptions();
1002 }
1003 }
BaseObject::getObjectinfo
virtual QString getObjectinfo()
Get all Info for the Object as a string.
Definition: BaseObject.cc:244
GroupObject
Definition: GroupObject.hh:69
LOGERR
Definition: LoggingInterface.hh:96
Core::slotFileOpened
void slotFileOpened(int _id)
Called when a file has been opened.
Definition: openFunctions.cc:696
Core::slotEmptyObjectAdded
void slotEmptyObjectAdded(int _id)
Called when an empty object has been Added.
Definition: openFunctions.cc:762
ApplicationStatus::READY
Status is ready (green light)
Definition: StatusbarInterface.hh:65
Core::slotAddEmptyObject
void slotAddEmptyObject(DataType _type, int &_id)
Slot adding empty object of a given type.
Definition: openFunctions.cc:502
Core::root_node_scenegraph_
SeparatorNode * root_node_scenegraph_
Scenegraphs root node.
Definition: Core.hh:1079
Core::slotLoad
void slotLoad(QString _filename, DataType _type, int &_id)
A plugin wants to load a given file.
Definition: openFunctions.cc:685
Core::signalObjectUpdated
void signalObjectUpdated(int)
When this Signal is emitted all Plugins are informed that the object list changed.
UPDATE_ALL
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
LoadWidget::showLoad
int showLoad()
show Widget for loading Files
Definition: loadWidget.cc:366
Core::supportedDataTypes_
std::vector< dataTypes > supportedDataTypes_
Type-Plugins.
Definition: Core.hh:1589
Core::objectRoot_
BaseObject * objectRoot_
Pointer to the data rootNode;.
Definition: Core.hh:1593
Core::openIniFile
void openIniFile(QString _filename, bool _coreSettings, bool _perPluginSettings, bool _loadObjects)
Load information from an ini file.
Definition: ParseIni.cc:400
Core::createBackup
void createBackup(int _objectid, QString _name, UpdateType _type=UPDATE_ALL)
Tell backup-plugin to create a backup.
DataType::name
QString name() const
Return the name of this type as text.
Definition: Types.cc:416
Core::loadSettings
void loadSettings()
Load status from file.
Definition: openFunctions.cc:906
BaseObject
Definition: BaseObject.hh:82
Core::emptyObjectAdded
void emptyObjectAdded(int _id)
Tell the plugins that an empty object has been added.
Core::slotExecuteAfterStartup
void slotExecuteAfterStartup()
Executed after loading core completly to load files from commandline.
Definition: openFunctions.cc:128
PluginFunctions::getObject
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Definition: PluginFunctions.cc:296
Core::slotObjectUpdated
void slotObjectUpdated(int _identifier, const UpdateType &_type=UPDATE_ALL)
Called by the plugins if they changed something in the object list (deleted, added, or other property changes)
Definition: PluginCommunication.cc:75
PluginFunctions::getSceneGraphRootNode
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
Definition: PluginFunctions.cc:959
CoreWidget::logWidget_
LoggerWidget * logWidget_
Textedit at the bottom for log messages.
Definition: CoreWidget.hh:686
Core::executeFileScript
void executeFileScript(QString _filename)
Core scripting engine.
Core::commandLineOpen
void commandLineOpen(const QString &_filename, bool _asPolyMesh)
Load an object from the commandline on application start.
Definition: openFunctions.cc:98
OpenMesh::VectorT
Definition: Vector11T.hh:83
LOGWARN
Definition: LoggingInterface.hh:95
DATA_GROUP
const DataType DATA_GROUP(1)
Items used for Grouping.
OpenFlipperThread::startProcessing
void startProcessing()
start processing
Definition: OpenFlipperThread.cc:112
LoadFromPluginThread
Definition: OpenFunctionThread.hh:11
DataType
Predefined datatypes.
Definition: DataTypes.hh:83
Core::addEmptyObject
int addEmptyObject(DataType _type)
Definition: openFunctions.cc:477
typeCount
DLLEXPORT size_t typeCount()
Get the number of registered types.
Definition: Types.cc:175
CoreWidget::addRecent
void addRecent(QString _filename, DataType _type)
Add a recent file and update menu.
Definition: CoreWidget.cc:860
BaseObject::id
int id() const
Definition: BaseObject.cc:190
Core::log
void log(Logtype _type, QString _message)
Logg with OUT,WARN or ERR as type.
Core::executePythonScriptFile
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:417
Core::applyOptions
void applyOptions()
after ini-files have been loaded and core is up or if options have been changed -> apply Options ...
Definition: optionHandling.cc:63
BaseObject::childExists
BaseObject * childExists(int _objectId)
Check if the element exists in the subtree of this element.
Definition: BaseObject.cc:516
BaseObject::dataType
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
IdList
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:179
Core::loadObjectFinished
void loadObjectFinished(QString _filename)
Vector storing filenames from commandline to be opened after application startup (objects) ...
Definition: openFunctions.cc:208
LoadFromPluginThread::LoadInfos
Definition: OpenFunctionThread.hh:16
Core::coreWidget_
CoreWidget * coreWidget_
The main applications widget ( only created in gui mode )
Definition: Core.hh:1596
BaseObject::parent
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:466
Core::commandLineFileNames_
std::vector< std::pair< QString, bool > > commandLineFileNames_
Vector storing filenames from commandline to be opened after application startup (objects) ...
Definition: Core.hh:888
Core::slotCall
void slotCall(QString _pluginName, QString _functionName, bool &_success)
Definition: RPC.cc:94
BaseObject::setParent
void setParent(BaseObject *_parent)
Set the parent pointer.
Definition: BaseObject.cc:477
Core::slotCopyObject
void slotCopyObject(int _oldId, int &_newId)
Slot copying an object.
Definition: openFunctions.cc:527
LoadWidget
Definition: loadWidget.hh:56
ACG::SceneGraph::analyzeSceneGraph
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
Definition: SceneGraphAnalysis.cc:56
SceneGraphAnalysis.hh
Core::exitApplication
void exitApplication()
exit the current application
Definition: Core.cc:1056
Core::slotSetJobState
void slotSetJobState(QString _jobId, int _value)
A job state has been updated by a plugin.
Definition: process.cc:141
Core::slotPluginExists
void slotPluginExists(QString _pluginName, bool &_exists)
Check if a plugin exists.
Definition: RPC.cc:63
Core::slotGetAllFilters
void slotGetAllFilters(QStringList &_list)
Called when a plugin requests a list of file-filters.
Definition: openFunctions.cc:88
Core::slotAddEmptyObjectMenu
void slotAddEmptyObjectMenu()
Open the add Empty dialog.
Definition: openFunctions.cc:799
Core::openedFile
void openedFile(int _id)
Tell the plugins that a file has been opened ( -> Database)
BaseObjectData
Definition: BaseObjectData.hh:102
Core.hh
typeName
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:154
CoreWidget::examiner_widgets_
std::vector< glViewer *> examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:677
addEmptyWidget
Definition: addEmptyWidget.hh:48
Core::commandLineScript
void commandLineScript(const QString &_filename)
Load a script from the commandline on application start.
Definition: openFunctions.cc:113
Core::updateView
void updateView()
Called when a plugin requests an update in the viewer.
Definition: Core.cc:943
Core::slotFinishJob
void slotFinishJob(QString _jobId)
A job state has been finished by a plugin.
Definition: process.cc:238
CoreWidget::updateInSceneLoggerGeometry
void updateInSceneLoggerGeometry()
Set in-scene logger geometry right.
Definition: LoggerHandling.cc:151
Core::slotStartJob
void slotStartJob(QString _jobId, QString _description, int _min, int _max, bool _blocking)
A job has been started by a plugin.
Definition: process.cc:64
Viewer::ViewerProperties::unLockUpdate
void unLockUpdate()
Unlock display locked by updateLock().
Definition: ViewerProperties.cc:262
PluginFunctions::viewerProperties
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
Definition: PluginFunctions.cc:611
Core::checkSlot
bool checkSlot(QObject *_plugin, const char *_slotSignature)
Check if a plugin has a slot.
Definition: PluginLoader.cc:254
Core::loadObject
void loadObject()
Open Load Widget.
Definition: openFunctions.cc:883
ApplicationStatus::PROCESSING
Status is processing but system will allow interaction (yellow light)
Definition: StatusbarInterface.hh:66
Core::commandLineScriptNames_
std::vector< QString > commandLineScriptNames_
Vector storing filenames from commandline to be opened after application startup (script files) ...
Definition: Core.hh:891
OpenFlipperQSettings::setValue
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
Definition: OpenFlipperQSettings.cc:61
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:1038
Core::resetScenegraph
void resetScenegraph(bool _resetTrackBall)
Definition: openFunctions.cc:62
Viewer::ViewerProperties::lockUpdate
void lockUpdate()
Definition: ViewerProperties.cc:258
Core::saveObject
bool saveObject(int _id, QString _filename)
Save an object.
Definition: saveFunctions.cc:65
BaseObject::copy
virtual BaseObject * copy()
Returns a full copy of the object.
Definition: BaseObject.cc:769
DATA_UNKNOWN
const DataType DATA_UNKNOWN(0)
None of the other Objects.
typeId
DLLEXPORT DataType typeId(QString _name)
Given a dataType Identifier string this function will return the id of the datatype.
Definition: Types.cc:139
PluginFunctions::viewAll
void viewAll(int _viewer)
View the whole scene.
Definition: PluginFunctions.cc:863
LOGINFO
Definition: LoggingInterface.hh:94