Developer Documentation
PythonInterpreter.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 #define PYTHON_DEBUG true
43 
44 #include <pybind11/include/pybind11/pybind11.h>
45 #include <pybind11/include/pybind11/embed.h>
46 #include <pybind11/include/pybind11/numpy.h>
47 
48 
49 #include "PyLogHook.h"
50 
51 #include "PythonInterpreter.hh"
52 
53 #include <QMetaObject>
54 #include <QMetaMethod>
55 
56 #include "PythonTypeConversions.hh"
57 
58 #include <OpenFlipper/BasePlugin/PythonFunctionsCore.hh>
59 
60 namespace py = pybind11;
61 
62 static Core* core_;
63 
64 static pybind11::module mainModule_;
65 
66 static PythonInterpreter* interpreter_ = nullptr;
67 
71 static PyObject* global_dict_clean_ = nullptr;
72 
73 
74 void setCorePointer( Core* _core ) {
75  core_ = _core;
76 }
77 
79 
80  if (interpreter_ == nullptr)
81  {
82  interpreter_ = new PythonInterpreter();
83  }
84 
85  return interpreter_;
86 
87 }
88 
90  externalLogging_(true)
91 {
92 
93 }
94 
95 PythonInterpreter::~PythonInterpreter() {
96 
97 }
98 
101  return static_cast<bool>(mainModule_);
102 }
103 
105 
106  if (Py_IsInitialized() ) {
107  #ifdef PYTHON_DEBUG
108  std::cerr << "Python already Initialized!" << std::endl;
109  #endif
110  return;
111  }
112 
113  #ifdef PYTHON_DEBUG
114  std::cerr << "Initialize interpreter ... " ;
115  #endif
116 
117  py::initialize_interpreter();
118 
119  #ifdef PYTHON_DEBUG
120  std::cerr << " Done" << std::endl;
121  std::cerr << "Initialize Threads ...";
122  #endif
123 
124  PyEval_InitThreads();
125 
126  #ifdef PYTHON_DEBUG
127  std::cerr << " Done" << std::endl;
128  #endif
129 
130  if (!modulesInitialized()) {
131  #ifdef PYTHON_DEBUG
132  std::cerr << "Import __main__" ;
133  #endif
134 
135  //dlopen("libpython3.5m.so.1.0", RTLD_LAZY | RTLD_GLOBAL);
136  py::module main{ py::module::import("__main__") };
137 
138  #ifdef PYTHON_DEBUG
139  std::cerr << " Done" << std::endl;
140  std::cerr << "Redirect Outputs ...";
141  #endif
142 
143  // Redirect python output to integrated logger functions
144  tyti::pylog::redirect_stderr([this](const char*w) {this->pyError(w); });
145  tyti::pylog::redirect_stdout([this](const char* w) {this->pyOutput(w); });
146 
147  #ifdef PYTHON_DEBUG
148  std::cerr << " Done" << std::endl;
149  std::cerr << "Get __dict__ from main namespace ...";
150  #endif
151 
152  // =========================================================
153  // Add OpenFlipper Core module to main namespace
154  // =========================================================
155  py::object main_namespace = main.attr("__dict__");
156 
157  #ifdef PYTHON_DEBUG
158  std::cerr << " Done" << std::endl;
159  std::cerr << "Importing OpenFlipper core module ...";
160  #endif
161 
162  py::module of_module(py::module::import("openflipper"));
163  main_namespace["openflipper"] = of_module;
164 
165  #ifdef PYTHON_DEBUG
166  std::cerr << " Done" << std::endl;
167  #endif
168 
169  // =========================================================
170  // Import with python interface to main namespace
171  // =========================================================
172 
173  QStringList pythonPlugins = getPythonPlugins();
174 
175  for ( int i = 0 ; i < pythonPlugins.size() ; ++i ) {
176 
177  #ifdef PYTHON_DEBUG
178  std::cerr << "Importing "+ pythonPlugins[i].toStdString() + " module ...";
179  #endif
180 
181  py::module om_module(py::module::import(pythonPlugins[i].toStdString().c_str()));
182  main_namespace[pythonPlugins[i].toStdString().c_str()] = om_module;
183 
184  #ifdef PYTHON_DEBUG
185  std::cerr << " Done" << std::endl;
186  #endif
187  }
188 
189  #ifdef PYTHON_DEBUG
190  std::cerr << "Copy dict ...";
191  #endif
192 
193  global_dict_clean_ = PyDict_Copy(PyModule_GetDict(main.ptr()));
194 
195  #ifdef PYTHON_DEBUG
196  std::cerr << " Done" << std::endl;
197  std::cerr << "Set to validate state ...";
198  #endif
199 
200  // set the main module member to a validate state, shows, that all modules are successfully initialized
201  mainModule_ = std::move(main);
202 
203  #ifdef PYTHON_DEBUG
204  std::cerr << " Done" << std::endl;
205  std::cerr << "Save thread ...";
206  #endif
207 
208  // Do not release the GIL until all modules are initalzed
209  PyEval_SaveThread();
210 
211  #ifdef PYTHON_DEBUG
212  std::cerr << " Done" << std::endl;
213  #endif
214 
215 
216  }
217 
218 }
219 
221 {
222  if (!Py_IsInitialized() || !modulesInitialized())
223  return;
224 
225  PyGILState_STATE state = PyGILState_Ensure();
226  PyObject* dict = PyModule_GetDict(mainModule_.ptr());
227  PyDict_Clear(dict);
228  PyDict_Update(dict, global_dict_clean_);
229  PyGILState_Release(state);
230 }
231 
232 
233 bool PythonInterpreter::runScript(QString _script) {
234 
235 #ifdef PYTHON_DEBUG
236  std::cerr << "runScript" << std::endl;
237 #endif
238 
239  //============================================================
240  // Prepend module instance getter to the script
241  //============================================================
242 
243  _script.prepend("core = openflipper.Core()\n");
244 
245  QStringList pythonPlugins = getPythonPlugins();
246 
247  for ( int i = 0 ; i < pythonPlugins.size() ; ++i ) {
248  QString import = pythonPlugins[i].toLower() + " = " + pythonPlugins[i] + "." + pythonPlugins[i] + "()\n";
249  _script.prepend(import);
250  }
251 
252  // Try to initialize python system
253  try
254  {
255 
256  #ifdef PYTHON_DEBUG
257  std::cerr << "Initialize Python" << std::endl;
258  #endif
259 
260  initPython();
261 
262  #ifdef PYTHON_DEBUG
263  std::cerr << "Done initializing Python" << std::endl;
264  #endif
265  }
266  catch (py::error_already_set &e)
267  {
268  pyError(e.what());
269  return false;
270  }
271 
272  PyGILState_STATE state = PyGILState_Ensure();
273  //PyThreadState* tstate = PyGILState_GetThisThreadState();
274 
275  auto locals = mainModule_.attr("__dict__");
276 
277  bool result = true;
278 
279  try
280  {
281 
282  std::cerr << "Now executing script:" << std::endl;
283  std::cerr << _script.toStdString() << std::endl;
284 
285  py::exec(_script.toStdString(), py::globals(), locals);
286 
287  std::cerr << "Finished successfully" << std::endl;
288  }
289  catch (py::error_already_set &e)
290  {
291  pyError(e.what());
292  e.restore();
293  result = false;
294  }
295  catch (const std::runtime_error &e)
296  {
297  pyError(e.what());
298  pyOutput("Restarting Interpreter.");
300  result = false;
301  state = PyGILState_Ensure();
302  }
303 
304  PyGILState_Release(state);
305 
306  return result;
307 }
308 
309 QString PythonInterpreter::runScriptOutput(QString _script) {
310  LogOut.clear();
311  LogErr.clear();
312  externalLogging_ = false;
313  runScript(_script);
314  externalLogging_ = true;
315  return LogOut + LogErr;
316 }
317 
318 
319 // Python callback functions
320 void PythonInterpreter::pyOutput(const char* w)
321 {
322  if (externalLogging_) {
323  emit log(LOGOUT, QString(w));
324  } else {
325  LogOut += QString::fromUtf8(w);
326  }
327 }
328 
329 void PythonInterpreter::pyError(const char* w)
330 {
331  if (externalLogging_) {
332  if (OpenFlipper::Options::nogui()) {
333  std::cerr << "Python Error! " << w << std::endl;
334  exit(1);
335  }
336  emit log(LOGERR, QString(w));
337  } else {
338  LogErr += QString::fromUtf8(w);
339  }
340 }
341 
342 
343 
344 
345 PYBIND11_EMBEDDED_MODULE(openflipper, m) {
346 
347  // Export our core. Make sure that the c++ worlds core objet is not deleted if
348  // the python side gets deleted!!
349  py::class_<Core,std::unique_ptr<Core, py::nodelete>> core(m, "Core");
350 
351  // On the c++ side we will just return the existing core instance
352  // and prevent the system to recreate a new core as we need
353  // to work on the existing one.
354  core.def(py::init([]() { return core_; }));
355 
356  core.def("updateView", &Core::updateView, QCoreApplication::translate("PythonDocCore","Redraw the contents of the viewer.").toLatin1().data() );
357  core.def("blockScenegraphUpdates", &Core::blockScenegraphUpdates, QCoreApplication::translate("PythonDocCore","Disable Scenegraph Updates (e.g. before loading or adding a large number of files)").toLatin1().data() );
358  core.def("updateUI", &Core::updateUI, QCoreApplication::translate("PythonDocCore","Process events during script execution to keep the ui alive").toLatin1().data() );
359  core.def("clearAll", &Core::clearAll, QCoreApplication::translate("PythonDocCore","Clear all data objects.").toLatin1().data() );
360  core.def("deleteObject", &Core::deleteObject, QCoreApplication::translate("PythonDocCore","Delete an object from the scene.").toLatin1().data() ,
361  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to delete.").toLatin1().data() ) );
362 
363  core.def("setObjectComment", &Core::setObjectComment, QCoreApplication::translate("PythonDocCore","Add a comment to an object (saved e.g. in screenshot metadata).").toLatin1().data()) ,
364  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to add comment.").toLatin1().data()),
365  py::arg( QCoreApplication::translate("PythonDocCore","Key value").toLatin1().data()),
366  py::arg( QCoreApplication::translate("PythonDocCore","Actual comment").toLatin1().data());
367 
368  core.def("clearObjectComment", &Core::clearObjectComment, QCoreApplication::translate("PythonDocCore","Remove a comment from an object.").toLatin1().data()) ,
369  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to remove comment from.").toLatin1().data()),
370  py::arg( QCoreApplication::translate("PythonDocCore","Key value to remove").toLatin1().data());
371 
372  core.def("clearAllComments", &Core::clearObjectComment, QCoreApplication::translate("PythonDocCore","Remove all comments from an object.").toLatin1().data()) ,
373  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to remove comments from.").toLatin1().data());
374 
375  core.def("fullscreen", &Core::fullscreen, QCoreApplication::translate("PythonDocCore","Enable or disable fullscreen mode.").toLatin1().data() ,
376  py::arg( QCoreApplication::translate("PythonDocCore","Enable or disable?").toLatin1().data() ) );
377 
378  core.def("showViewModeControls", &Core::deleteObject, QCoreApplication::translate("PythonDocCore","Show or hide the view mode control box").toLatin1().data() ,
379  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
380 
381  core.def("loggerState", &Core::loggerState, QCoreApplication::translate("PythonDocCore","Change the logger window state").toLatin1().data() ,
382  py::arg( QCoreApplication::translate("PythonDocCore","0 = In Scene , 1 = Normal, 2 = Hidden").toLatin1().data() ) );
383 
384  core.def("enableOpenMeshErrorLog", &Core::enableOpenMeshErrorLog, QCoreApplication::translate("PythonDocCore","Enable or disable OpenMesh error logging").toLatin1().data() ,
385  py::arg( QCoreApplication::translate("PythonDocCore","Enable or Disable").toLatin1().data() ) );
386 
387  core.def("showToolbox", &Core::showToolbox, QCoreApplication::translate("PythonDocCore","Show or hide toolbox").toLatin1().data() ,
388  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
389 
390  core.def("showStatusBar", &Core::showStatusBar, QCoreApplication::translate("PythonDocCore","Show or hide status bar").toLatin1().data() ,
391  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
392 
393  core.def("multiViewMode", &Core::multiViewMode, QCoreApplication::translate("PythonDocCore","Switch MultiView Mode").toLatin1().data() ,
394  py::arg( QCoreApplication::translate("PythonDocCore","0: One Viewer, 1: Double Viewer, 2: Grid, 3: Horizontal split").toLatin1().data() ) );
395 
396  core.def("restrictFrameRate", &Core::restrictFrameRate, QCoreApplication::translate("PythonDocCore","Restrict maximal rendering FrameRate to MaxFrameRate").toLatin1().data() ,
397  py::arg( QCoreApplication::translate("PythonDocCore","Restrict Framerate?").toLatin1().data() ) );
398 
399  core.def("setMaxFrameRate", &Core::setMaxFrameRate, QCoreApplication::translate("PythonDocCore","Set the maximal framerate (automatically enables framerate restriction)").toLatin1().data() ,
400  py::arg( QCoreApplication::translate("PythonDocCore","Maximum frameRate").toLatin1().data() ) );
401 
402  core.def("snapshotBaseFileName", &Core::snapshotBaseFileName, QCoreApplication::translate("PythonDocCore","Set a base filename for storing snapshots. This setting is viewer dependent").toLatin1().data() ,
403  py::arg( QCoreApplication::translate("PythonDocCore","Base filename").toLatin1().data()),
404  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the filename for").toLatin1().data() ) );
405 
406  core.def("snapshotFileType", &Core::snapshotFileType, QCoreApplication::translate("PythonDocCore","Set a filetype for storing snapshots.").toLatin1().data() ,
407  py::arg( QCoreApplication::translate("PythonDocCore","Image type as string (e.g. jpg )").toLatin1().data()),
408  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the filetype for").toLatin1().data() ) );
409 
410  core.def("snapshotCounterStart", &Core::snapshotCounterStart, QCoreApplication::translate("PythonDocCore","Set the starting number for the snapshot counter.").toLatin1().data() ,
411  py::arg( QCoreApplication::translate("PythonDocCore","Starting number for the counter").toLatin1().data() ),
412  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the counter for").toLatin1().data() ) );
413 
414 
415  core.def("snapshot", &Core::snapshot, QCoreApplication::translate("PythonDocCore", "Make a snapshot of the viewer with id viewerId.\n"
416  "Pass 0 as viewerId parameter to capture the current viewer. \n"
417  "The captured image will have the specified dimensions. \n"
418  "If 0 is passed as either width or height parameter, the value will \n"
419  "automatically be set to hold the right aspect ratio, respectively. \n"
420  "If 0 is passed for both width and height values, the viewport's current \n"
421  "dimension is used. Set alpha to true if you want the background to be transparent. \n"
422  "The fifth parameter is used to hide the coordinate system in the upper right corner of the screen. \n"
423  "If no filename was set using snapshotBaseFileName() the snapshot is stored \n"
424  "in snap.png in the current directory. For every snapshot \n"
425  "a counter is added to the filename.").toLatin1().data() ,
426  py::arg( QCoreApplication::translate("PythonDocCore","Id of viewer").toLatin1().data() ) = 0,
427  py::arg( QCoreApplication::translate("PythonDocCore","Width of image").toLatin1().data() )= 0,
428  py::arg( QCoreApplication::translate("PythonDocCore","Height of image").toLatin1().data() )= 0,
429  py::arg( QCoreApplication::translate("PythonDocCore","Transparent background?").toLatin1().data() ) = false,
430  py::arg( QCoreApplication::translate("PythonDocCore","Hide coordinate system?").toLatin1().data() ) = false ,
431  py::arg( QCoreApplication::translate("PythonDocCore","Number of samples per pixel").toLatin1().data() ) =1 );
432 
433 
434  core.def("applicationSnapshot", &Core::applicationSnapshot, QCoreApplication::translate("PythonDocCore","Create a snapshot of the whole application").toLatin1().data() );
435 
436  core.def("applicationSnapshotName", &Core::applicationSnapshotName, QCoreApplication::translate("PythonDocCore","Set the baseName for the application snapshot").toLatin1().data() ,
437  py::arg( QCoreApplication::translate("PythonDocCore","BaseName for full application snapshots").toLatin1().data() ) );
438 
439  core.def("viewerSnapshot", static_cast<void (Core::*)()>(&Core::viewerSnapshot), QCoreApplication::translate("PythonDocCore","Take a snapshot from all viewers").toLatin1().data() );
440 
441  core.def("viewerSnapshot", static_cast<void (Core::*)(QString,bool,bool,bool,bool,int,int,bool,bool,int,bool)>(&Core::viewerSnapshot),
442  QCoreApplication::translate("PythonDocCore","Create a snapshot with full control").toLatin1().data(),
443  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the snapshot").toLatin1().data() ),
444  py::arg( QCoreApplication::translate("PythonDocCore","Should the comments be written?").toLatin1().data() ),
445  py::arg( QCoreApplication::translate("PythonDocCore","Should only the comments of visible objects be written?").toLatin1().data() ),
446  py::arg( QCoreApplication::translate("PythonDocCore","Should only the comments of target objects be written?").toLatin1().data() ),
447  py::arg( QCoreApplication::translate("PythonDocCore","Store material info?").toLatin1().data() ),
448  py::arg( QCoreApplication::translate("PythonDocCore","Snapshot width").toLatin1().data() ),
449  py::arg( QCoreApplication::translate("PythonDocCore","Snapshot height").toLatin1().data() ),
450  py::arg( QCoreApplication::translate("PythonDocCore","Transparent background?").toLatin1().data() ),
451  py::arg( QCoreApplication::translate("PythonDocCore","Hide coordinate system?").toLatin1().data() ),
452  py::arg( QCoreApplication::translate("PythonDocCore","Multisampling count").toLatin1().data() ),
453  py::arg( QCoreApplication::translate("PythonDocCore","Store the view in the metadata?").toLatin1().data() ) );
454 
455 
456  core.def("resizeViewers", &Core::resizeViewers, QCoreApplication::translate("PythonDocCore","Resize the examinerViewer.").toLatin1().data() ,
457  py::arg( QCoreApplication::translate("PythonDocCore","Width").toLatin1().data() ),
458  py::arg( QCoreApplication::translate("PythonDocCore","Height").toLatin1().data() ) );
459 
460  core.def("resizeApplication", &Core::resizeApplication, QCoreApplication::translate("PythonDocCore","Resize the whole Application.").toLatin1().data() ,
461  py::arg( QCoreApplication::translate("PythonDocCore","Width").toLatin1().data() ),
462  py::arg( QCoreApplication::translate("PythonDocCore","Height").toLatin1().data() ) );
463 
464  core.def("writeVersionNumbers", &Core::writeVersionNumbers, QCoreApplication::translate("PythonDocCore","Write the current versions of all plugins to ini file").toLatin1().data() ,
465  py::arg( QCoreApplication::translate("PythonDocCore","Full path to a file where the versions should be written to.").toLatin1().data() ) );
466 
467 // core.def("objectList", &Core::objectList, QCoreApplication::translate("PythonDocCore","Return an id list of available object that has the given selection and type").toLatin1().data() ,
468 // py::arg( QCoreApplication::translate("PythonDocCore","Either source or target").toLatin1().data()) ,
469 // py::arg( QCoreApplication::translate("PythonDocCore","Object types as a stringlist").toLatin1().data() ));
470 
471 // /// return the list of available object that has the given selection and type
472 // QList<int> objectList (QString _selection, QStringList _types);
473 
474  core.def("blockSceneGraphUpdates", &Core::blockSceneGraphUpdates, QCoreApplication::translate("PythonDocCore","Block the scenegraph updates for improved performance").toLatin1().data() );
475  core.def("unblockSceneGraphUpdates", &Core::unblockSceneGraphUpdates, QCoreApplication::translate("PythonDocCore","Unblock the scenegraph updates").toLatin1().data() );
476 
477 
478  core.def("setView", &Core::setView, QCoreApplication::translate("PythonDocCore","Set the encoded view for the primary viewport.").toLatin1().data() ,
479  py::arg( QCoreApplication::translate("PythonDocCore","The encoded view. (You can obtain one through \"Copy View\" in the context menu of the coordinates.)").toLatin1().data() ) );
480 
481  core.def("setViewAndWindowGeometry", &Core::setViewAndWindowGeometry, QCoreApplication::translate("PythonDocCore","Set the encoded view for the primary viewport and the full geometry of the application").toLatin1().data() ,
482  py::arg( QCoreApplication::translate("PythonDocCore","The encoded view. (You can obtain one through \"Copy View\" in the context menu of the coordinates.)").toLatin1().data() ) );
483 
484  core.def("addViewModeToolboxes", &Core::addViewModeToolboxes, QCoreApplication::translate("PythonDocCore","Set toolboxes for a viewmode (This automatically adds the view mode if it does not exist)").toLatin1().data() ,
485  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
486  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of toolboxes visible in this viewmode)").toLatin1().data() ));
487 
488  core.def("addViewModeToolbars", &Core::addViewModeToolbars, QCoreApplication::translate("PythonDocCore","Set toolbars for a viewmode (This automatically adds the view mode if it does not exist)").toLatin1().data() ,
489  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
490  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of toolbars visible in this viewmode)").toLatin1().data() ));
491 
492  core.def("addViewModeContextMenus", &Core::addViewModeContextMenus, QCoreApplication::translate("PythonDocCore","Set context Menus for a viewmode (This automatically adds the view mode if it does not exist)").toLatin1().data() ,
493  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
494  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of Context Menus visible in this viewmode)").toLatin1().data() ));
495 
496  core.def("addViewModeIcon", &Core::addViewModeIcon, QCoreApplication::translate("PythonDocCore","Set Icon for a viewmode (This automatically adds the view mode if it does not exist)").toLatin1().data() ,
497  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
498  py::arg( QCoreApplication::translate("PythonDocCore","filename of the icon (will be taken from OpenFlippers icon directory)").toLatin1().data() ));
499 
500 
501  core.def("setToolBoxSide", &Core::setToolBoxSide, QCoreApplication::translate("PythonDocCore","Scripting function to set the side of the main window on which the toolbox should be displayed").toLatin1().data() ,
502  py::arg( QCoreApplication::translate("PythonDocCore","The desired side of the toolboxes (either 'left' or 'right')").toLatin1().data() ) );
503 
504  core.def("setToolBoxActive", &Core::setToolBoxActive, QCoreApplication::translate("PythonDocCore","Activate or deaktivate a toolbox").toLatin1().data() ,
505  py::arg( QCoreApplication::translate("PythonDocCore","Name of the toolbox.").toLatin1().data() ),
506  py::arg( QCoreApplication::translate("PythonDocCore","Activate or deaktivate?").toLatin1().data() ));
507 
508  core.def("loadObject", static_cast<int (Core::*)(QString)>(&Core::loadObject), QCoreApplication::translate("PythonDocCore","Load an object specified in file filename. This automatically determines which file plugin to use. It returns the id of the object in the scene or -1 on failure").toLatin1().data() ,
509  py::arg( QCoreApplication::translate("PythonDocCore","Filename to load.").toLatin1().data() ) );
510 
511  core.def("startVideoCapture", &Core::startVideoCapture, QCoreApplication::translate("PythonDocCore","Start video capturing.").toLatin1().data() ,
512  py::arg( QCoreApplication::translate("PythonDocCore","Basename for capturing").toLatin1().data() ),
513  py::arg( QCoreApplication::translate("PythonDocCore","Frames per second").toLatin1().data() ),
514  py::arg( QCoreApplication::translate("PythonDocCore","Should the viewers be captured or the whole application?").toLatin1().data() ) );
515 
516  core.def("stopVideoCapture", &Core::stopVideoCapture, QCoreApplication::translate("PythonDocCore","Stop video capturing").toLatin1().data() );
517 
518  core.def("saveObject", static_cast<bool (Core::*)(int,QString)>(&Core::saveObject), QCoreApplication::translate("PythonDocCore","Save object to file. If the file exists it will be overwritten.").toLatin1().data() ,
519  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object)").toLatin1().data() ),
520  py::arg( QCoreApplication::translate("PythonDocCore","Complete path and filename").toLatin1().data() ));
521 
522  core.def("saveObjectTo", static_cast<bool (Core::*)(int,QString)>(&Core::saveObjectTo), QCoreApplication::translate("PythonDocCore","Save object to file. The location can be chosen in a dialog. (GUI mode only!)").toLatin1().data() ,
523  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object)").toLatin1().data() ),
524  py::arg( QCoreApplication::translate("PythonDocCore","Initial filename in the dialog").toLatin1().data() ));
525 
526 
527 // bool saveObjectsTo( IdList _ids, QString _filename );
528 
529 
530  core.def("saveAllObjects", &Core::saveAllObjects, QCoreApplication::translate("PythonDocCore","Saves all target objects. Exising files will be overriden. For new files, a dialog is shown (Only GUI Mode!)").toLatin1().data() );
531 
532  core.def("saveAllObjectsTo", &Core::saveAllObjectsTo, QCoreApplication::translate("PythonDocCore","Saves all target objects. The locations can be chosen in dialogs. (Only GUI Mode!)").toLatin1().data() );
533 
534  core.def("saveSettings", static_cast<void (Core::*)()>(&Core::saveSettings), QCoreApplication::translate("PythonDocCore","Show the dialog to save settings. (only works if GUI is available)").toLatin1().data() );
535 
536  core.def("saveSettings", static_cast<void (Core::*)(QString,bool,bool,bool,bool,bool,bool)>(&Core::saveSettings),
537  QCoreApplication::translate("PythonDocCore","Save the current setting to the given file.").toLatin1().data(),
538  py::arg( QCoreApplication::translate("PythonDocCore","Path of the file to save the settings to.").toLatin1().data() ),
539  py::arg( QCoreApplication::translate("PythonDocCore","Save Object information into file?").toLatin1().data() ),
540  py::arg( QCoreApplication::translate("PythonDocCore","Restrict to targeted objects?").toLatin1().data() ),
541  py::arg( QCoreApplication::translate("PythonDocCore","Save objects into same path as settings file?").toLatin1().data() ),
542  py::arg( QCoreApplication::translate("PythonDocCore","Prompt before overwriting files that already exist (gui mode only).").toLatin1().data() ),
543  py::arg( QCoreApplication::translate("PythonDocCore","Save program settings?").toLatin1().data() ),
544  py::arg( QCoreApplication::translate("PythonDocCore","Save plugin settings?").toLatin1().data() ) );
545 
546  core.def("loadObject", static_cast<void (Core::*)()>(&Core::loadObject), QCoreApplication::translate("PythonDocCore","Show the dialog to load an object. (only works if GUI is available)").toLatin1().data() );
547 
548  core.def("loadSettings", static_cast<void (Core::*)()>(&Core::loadSettings), QCoreApplication::translate("PythonDocCore","Show the dialog to load settings. (only works if GUI is available)").toLatin1().data() );
549 
550  core.def("loadSettings", static_cast<void (Core::*)(QString)>(&Core::loadSettings), QCoreApplication::translate("PythonDocCore","Load settings from file.").toLatin1().data() ,
551  py::arg( QCoreApplication::translate("PythonDocCore","Filename to load.").toLatin1().data() ) );
552 
553  core.def("getObjectId", &Core::getObjectId, QCoreApplication::translate("PythonDocCore","Return identifier of object with specified name. Returns -1 if object was not found.").toLatin1().data() ,
554  py::arg( QCoreApplication::translate("PythonDocCore","Filename or name of the object").toLatin1().data() ) );
555 
556  core.def("deserializeMaterialProperties", &Core::deserializeMaterialProperties, QCoreApplication::translate("PythonDocCore","Deserialize the supplied material properties into the supplied object.").toLatin1().data() ,
557  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object").toLatin1().data() ),
558  py::arg( QCoreApplication::translate("PythonDocCore","Material properties encoded as string").toLatin1().data() ) );
559 
560  core.def("serializeMaterialProperties", &Core::serializeMaterialProperties, QCoreApplication::translate("PythonDocCore","Serialize and return the material properties of the supplied object.").toLatin1().data() ,
561  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object").toLatin1().data() ));
562 
563  core.def("activateToolbox", &Core::activateToolbox, QCoreApplication::translate("PythonDocCore","Expand or collapse a toolbox").toLatin1().data() ,
564  py::arg( QCoreApplication::translate("PythonDocCore","Name of the plugin to which this toolbox gelongs").toLatin1().data() ),
565  py::arg( QCoreApplication::translate("PythonDocCore","Name of the toolbox").toLatin1().data() ),
566  py::arg( QCoreApplication::translate("PythonDocCore","Expand or collapse?").toLatin1().data() ) );
567 
568  core.def("saveOptions", &Core::saveOptions, QCoreApplication::translate("PythonDocCore","Save the current options to the standard ini file").toLatin1().data() );
569 
570  core.def("applyOptions", &Core::applyOptions, QCoreApplication::translate("PythonDocCore","After ini-files have been loaded and core is up or if options have been changed -> apply Options").toLatin1().data() );
571 
572  core.def("openIniFile", &Core::openIniFile, QCoreApplication::translate("PythonDocCore","Load information from an ini file").toLatin1().data() ,
573  py::arg( QCoreApplication::translate("PythonDocCore","Name of the ini file").toLatin1().data() ),
574  py::arg( QCoreApplication::translate("PythonDocCore","Load applications settings?").toLatin1().data() ),
575  py::arg( QCoreApplication::translate("PythonDocCore","Load plugin settings?").toLatin1().data() ),
576  py::arg( QCoreApplication::translate("PythonDocCore"," Load objects defined in the ini file?").toLatin1().data() ));
577 
578 
579 // /** \brief Create an script object from a ui file
580 // *
581 // * This function will load an ui file, set up a qwidget from that and makes it available
582 // * under _objectName for scripting.
583 // * @param _objectName The name in scripting environment used for the new object
584 // * @param _uiFilename ui file to load
585 // */
586 // void createWidget(QString _objectName, QString _uiFilename, bool _show = true);
587 
588  core.def("setViewMode", &Core::setViewMode, QCoreApplication::translate("PythonDocCore","Switch to the given viewmode").toLatin1().data() ,
589  py::arg( QCoreApplication::translate("PythonDocCore","Name of the viewmode to enable").toLatin1().data() ) );
590 
591 
592  core.def("getCurrentViewMode", &Core::getCurrentViewMode, QCoreApplication::translate("PythonDocCore","Get the name of the current viewMode").toLatin1().data() );
593 
594  core.def("setViewModeIcon", &Core::setViewModeIcon, QCoreApplication::translate("PythonDocCore","Set an icon for a view Mode").toLatin1().data() ,
595  py::arg( QCoreApplication::translate("PythonDocCore","Name of the mode for the icon").toLatin1().data() ),
596  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the icon").toLatin1().data() ) );
597 
598  core.def("moveToolBoxToTop", &Core::moveToolBoxToTop, QCoreApplication::translate("PythonDocCore","Move selected toolbox to the top of side area").toLatin1().data() ,
599  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Toolbox to be moved").toLatin1().data() ) );
600 
601  core.def("moveToolBoxToBottom", &Core::moveToolBoxToBottom, QCoreApplication::translate("PythonDocCore","Move selected toolbox to the bottom of side area").toLatin1().data() ,
602  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Toolbox to be moved").toLatin1().data() ) );
603 
604  core.def("showReducedMenuBar", &Core::showReducedMenuBar, QCoreApplication::translate("PythonDocCore","Show only a reduced menubar").toLatin1().data() ,
605  py::arg( QCoreApplication::translate("PythonDocCore","Reduced Menubar?").toLatin1().data() ) );
606 
607  core.def("executePythonScriptFile", &Core::executePythonScriptFile, QCoreApplication::translate("PythonDocCore","Open the given file and execute its contents as a python script").toLatin1().data() ,
608  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the script").toLatin1().data() ) );
609 
610 
611  core.def("executePythonScript", &Core::executePythonScript, QCoreApplication::translate("PythonDocCore","Execute a text as a python script").toLatin1().data() ,
612  py::arg( QCoreApplication::translate("PythonDocCore","The text of the script").toLatin1().data() ) );
613 
614  core.def("exitApplication", &Core::exitApplication, QCoreApplication::translate("PythonDocCore","Exit the application").toLatin1().data() );
615  core.def("exitFailure", &Core::exitFailure, QCoreApplication::translate("PythonDocCore","Use this function in unit tests, if you detected a failure. Therefore the test functions will recognize that something went wrong.").toLatin1().data() );
616  core.def("finishSplash", &Core::finishSplash, QCoreApplication::translate("PythonDocCore","Hide the splash screen").toLatin1().data() );
617 
618  core.def("objectUpdated", &Core::slotObjectUpdated, QCoreApplication::translate("PythonDocCore","Tell the core that an object has been updated").toLatin1().data(),
619  py::arg( QCoreApplication::translate("PythonDocCore","ID of the updated object").toLatin1().data() ),
620  py::arg( QCoreApplication::translate("PythonDocCore","What has been updated? String list separated by ; . Possible update types include: All,Visibility,Geometry,Topology,Selection,VertexSelection,EdgeSelection,HalfedgeSelection,FaceSelection,KnotSelection,Color,Texture,State ").toLatin1().data() ) = UPDATE_ALL );
621 
622 
623 // //load slots
624 // emit setSlotDescription("createWidget(QString,QString)", tr("Create a widget from an ui file"),
625 // QString(tr("Object name,ui file")).split(","),
626 // QString(tr("Name of the new widget in script,ui file to load")).split(","));
627 
628 // emit setSlotDescription("objectList(QString,QStringList)", tr("Returns object list"),
629 // QString(tr("Selection type,Object types")).split(","),
630 
631 
632 
633 
634 }
635 
void saveAllObjectsTo()
Slot for saving objects to a new location.
void log(Logtype _type, QString _message)
Log with OUT,WARN or ERR as type.
void exitFailure()
Aborts the application with an error code.
Definition: Core.cc:1268
void resetInterpreter()
Resets the interpreter and all states.
void startVideoCapture(QString _baseName, int _fps, bool _captureViewers)
Start video capturing.
Definition: Video.cc:63
void clearAll()
Clear all data objects.
Definition: Core.cc:1043
void setToolBoxActive(QString _toolBoxName, bool _active)
Scripting function to activate or deactivate a toolbox.
Definition: scripting.cc:303
void snapshotFileType(QString _type, unsigned int _viewerId=0)
Set the file type for snapshots.
Definition: Core.cc:1467
void showStatusBar(bool _state)
Show or hide Status Bar.
Definition: Core.cc:1124
void showToolbox(bool _state)
Show or hide toolbox.
Definition: Core.cc:1117
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
PythonInterpreter()
private constructor because of singleton
void addViewModeToolbars(QString _modeName, QString _toolbarList)
Scripting function to set toolbars in a view mode.
Definition: scripting.cc:197
void saveOptions()
Save the current options to the standard ini file.
void openIniFile(QString _filename, bool _coreSettings, bool _perPluginSettings, bool _loadObjects)
Load information from an ini file.
Definition: ParseIni.cc:400
bool runScript(QString _script)
Run a script. Output is passed to the standard logging facilities of OpenFlipper. ...
void loadSettings()
Load status from file.
void fullscreen(bool _state)
set fullscreen mode
Definition: Core.cc:1068
static PythonInterpreter * getInstance()
Creates or returns an instance of the interpreter.
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: Core.hh:132
void setView(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:320
void deserializeMaterialProperties(int _objId, QString _props)
Serialize material properties.
Definition: Core.cc:1811
void deleteObject(int _id)
Called to delete an object.
Definition: Core.cc:1782
void setMaxFrameRate(int _rate)
set the maximal framerate ( automatically enables framerate restriction )
Definition: Core.cc:1032
QString runScriptOutput(QString _script)
void addViewModeContextMenus(QString _modeName, QString _contextMenuList)
Scripting function to set context menus in a view mode.
Definition: scripting.cc:205
void saveSettings()
Save current status to a settings file. Solicit file name through dialog.
Definition: saveSettings.cc:53
void executePythonScriptFile(QString _filename)
Open the given file and execute its contents as a python script.
Definition: scripting.cc:417
void applyOptions()
after ini-files have been loaded and core is up or if options have been changed -> apply Options ...
void updateUI()
process events during script execution to keep the ui alive
Definition: Core.cc:994
void resizeViewers(int _width, int _height)
resize the examinerViewer
Definition: Core.cc:1540
bool saveObjectTo(int _id, QString _filename)
This class provides OpenFlippers Python interpreter.
void snapshot(unsigned int _viewerId=0, int _width=0, int _height=0, bool _alpha=false, bool _hideCoordsys=false, int _numSamples=1)
Definition: Core.cc:1494
void resizeApplication(int _width, int _height)
resize the whole Application
Definition: Core.cc:1551
void loggerState(int _state)
Change the logging window state.
Definition: Core.cc:1083
void exitApplication()
exit the current application
Definition: Core.cc:1056
void multiViewMode(int _mode)
Switch the multiView Mode.
Definition: Core.cc:1131
void enableOpenMeshErrorLog(bool _state)
Enable or disable OpenMesh error logging.
Definition: Core.cc:1094
void snapshotCounterStart(const int _counter, unsigned int _viewerId=0)
Set the start index for the snapshot counter.
Definition: Core.cc:1481
void addViewModeToolboxes(QString _modeName, QString _toolboxList)
Scripting function to set toolboxes in a view mode.
Definition: scripting.cc:189
void setToolBoxSide(QString _side)
Scripting function to set the side of the main window on which the toolbox should be displayed...
Definition: scripting.cc:217
QString getCurrentViewMode()
Get current view mode.
Definition: scripting.cc:145
void unblockSceneGraphUpdates()
Unblock the scenegraph updates.
Definition: scripting.cc:316
void blockSceneGraphUpdates()
Block the scenegraph updates.
Definition: scripting.cc:311
void updateView()
Called when a plugin requests an update in the viewer.
Definition: Core.cc:943
void snapshotBaseFileName(QString _fname, unsigned int _viewerId=0)
Definition: Core.cc:1454
void setViewModeIcon(QString _mode, QString _iconName)
Set the icon of a viewMode.
Definition: scripting.cc:151
void saveAllObjects()
Slot for saving objects from Menu.
void pyOutput(const char *w)
Callback to redirect cout log to OpenFlipper logger.
void activateToolbox(QString _pluginName, QString _toolboxName, bool activate)
expand or collapse a toolbox
Definition: scripting.cc:248
void applicationSnapshotName(QString _name)
Set the baseName for the application snapshot.
Definition: Core.cc:1513
void pyError(const char *w)
Callback to redirect cerr log to OpenFlipper logger.
void showReducedMenuBar(bool reduced)
Core scripting engine.
Definition: Core.cc:2055
void setViewMode(QString _viewMode)
Set the active ViewMode.
Definition: scripting.cc:137
void loadObject()
Open Load Widget.
void finishSplash()
exit the current application
Definition: Core.cc:2059
void blockScenegraphUpdates(bool _block)
Called when a plugin wants to lock or unlock scenegraph updates.
Definition: Core.cc:1000
void moveToolBoxToTop(QString _name)
Move selected toolbox to top of side area.
Definition: scripting.cc:171
void addViewModeIcon(QString _modeName, QString _iconName)
Scripting function to set an icon for a view mode.
Definition: scripting.cc:211
QString serializeMaterialProperties(int _objId)
Serialize material properties.
Definition: Core.cc:1830
bool saveObject(int _id, QString _filename)
Save an object.
int getObjectId(QString _filename)
Get object id from filename.
Definition: scripting.cc:130
void viewerSnapshot()
Take a snapshot from all viewers.
Definition: Core.cc:1519
void clearObjectComment(int objId, QString key)
Called when a plugin requests an update in the viewer.
Definition: Core.cc:1863
void restrictFrameRate(bool _enable)
Enable or disable framerate restriction.
Definition: Core.cc:1026
void executePythonScript(QString _script)
execute the given string as a python script
Definition: scripting.cc:441
void setObjectComment(int objId, QString key, QString comment)
Called when a plugin requests an update in the viewer.
Definition: Core.cc:1850
void moveToolBoxToBottom(QString _name)
Move selected toolbox to bottom of side area.
Definition: scripting.cc:180
void setViewAndWindowGeometry(QString view)
Called when a plugin requests an update in the viewer.
Definition: scripting.cc:324
void applicationSnapshot()
Take a snapshot from the whole app.
Definition: Core.cc:1507
void writeVersionNumbers(QString _filename)
write the current versions of all plugins to ini file
Definition: Core.cc:1561
void stopVideoCapture()
Stop video capturing.
Definition: Video.cc:109
void initPython()
Initialize OpenFlipper Python Interpreter.