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_ = nullptr;
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 
144  // Redirect python output to integrated logger functions
145  // Try to redirect python output only when we are in gui mode. Otherwise just leave it on the console
146  if ( OpenFlipper::Options::gui() ) {
147  tyti::pylog::redirect_stderr([this](const char*w) {this->pyError(w); });
148  tyti::pylog::redirect_stdout([this](const char* w) {this->pyOutput(w); });
149  }
150 
151  #ifdef PYTHON_DEBUG
152  std::cerr << " Done" << std::endl;
153  std::cerr << "Get __dict__ from main namespace ...";
154  #endif
155 
156  // =========================================================
157  // Add OpenFlipper Core module to main namespace
158  // =========================================================
159  py::object main_namespace = main.attr("__dict__");
160 
161  #ifdef PYTHON_DEBUG
162  std::cerr << " Done" << std::endl;
163  std::cerr << "Importing OpenFlipper core module ...";
164  #endif
165 
166  py::module of_module(py::module::import("openflipper"));
167  main_namespace["openflipper"] = of_module;
168 
169  #ifdef PYTHON_DEBUG
170  std::cerr << " Done" << std::endl;
171  #endif
172 
173  // =========================================================
174  // Import with python interface to main namespace
175  // =========================================================
176 
177  QStringList pythonPlugins = getPythonPlugins();
178 
179  for ( int i = 0 ; i < pythonPlugins.size() ; ++i ) {
180 
181  #ifdef PYTHON_DEBUG
182  std::cerr << "Importing "+ pythonPlugins[i].toStdString() + " module ...";
183  #endif
184 
185  py::module om_module(py::module::import(pythonPlugins[i].toStdString().c_str()));
186  main_namespace[pythonPlugins[i].toStdString().c_str()] = om_module;
187 
188  #ifdef PYTHON_DEBUG
189  std::cerr << " Done" << std::endl;
190  #endif
191  }
192 
193  #ifdef PYTHON_DEBUG
194  std::cerr << "Copy dict ...";
195  #endif
196 
197  global_dict_clean_ = PyDict_Copy(PyModule_GetDict(main.ptr()));
198 
199  #ifdef PYTHON_DEBUG
200  std::cerr << " Done" << std::endl;
201  std::cerr << "Set to validate state ...";
202  #endif
203 
204  // set the main module member to a validate state, shows, that all modules are successfully initialized
205  mainModule_ = std::move(main);
206 
207  #ifdef PYTHON_DEBUG
208  std::cerr << " Done" << std::endl;
209  std::cerr << "Save thread ...";
210  #endif
211 
212  // Do not release the GIL until all modules are initalzed
213  PyEval_SaveThread();
214 
215  #ifdef PYTHON_DEBUG
216  std::cerr << " Done" << std::endl;
217  #endif
218 
219 
220  }
221 
222 }
223 
225 {
226  if (!Py_IsInitialized() || !modulesInitialized())
227  return;
228 
229  PyGILState_STATE state = PyGILState_Ensure();
230  PyObject* dict = PyModule_GetDict(mainModule_.ptr());
231  PyDict_Clear(dict);
232  PyDict_Update(dict, global_dict_clean_);
233  PyGILState_Release(state);
234 }
235 
236 
237 bool PythonInterpreter::runScript(QString _script) {
238 
239 #ifdef PYTHON_DEBUG
240  std::cerr << "runScript" << std::endl;
241 #endif
242 
243  //============================================================
244  // Prepend module instance getter to the script
245  //============================================================
246 
247  _script.prepend("core = openflipper.Core()\n");
248 
249  QStringList pythonPlugins = getPythonPlugins();
250 
251  for ( int i = 0 ; i < pythonPlugins.size() ; ++i ) {
252  QString import = pythonPlugins[i].toLower() + " = " + pythonPlugins[i] + "." + pythonPlugins[i] + "()\n";
253  _script.prepend(import);
254  }
255 
256  // Try to initialize python system
257  try
258  {
259 
260  #ifdef PYTHON_DEBUG
261  std::cerr << "Initialize Python" << std::endl;
262  #endif
263 
264  initPython();
265 
266  #ifdef PYTHON_DEBUG
267  std::cerr << "Done initializing Python" << std::endl;
268  #endif
269  }
270  catch (py::error_already_set &e)
271  {
272  pyError(e.what());
273  return false;
274  }
275 
276  PyGILState_STATE state = PyGILState_Ensure();
277  //PyThreadState* tstate = PyGILState_GetThisThreadState();
278 
279  auto locals = mainModule_.attr("__dict__");
280 
281  bool result = true;
282 
283  try
284  {
285 
286  std::cerr << "Now executing script:" << std::endl;
287  std::cerr << _script.toStdString() << std::endl;
288 
289  py::exec(_script.toStdString(), py::globals(), locals);
290 
291  std::cerr << "Finished successfully" << std::endl;
292  }
293  catch (py::error_already_set &e)
294  {
295  pyError(e.what());
296  e.restore();
297  result = false;
298  }
299  catch (const std::runtime_error &e)
300  {
301  pyError(e.what());
302  pyOutput("Restarting Interpreter.");
304  result = false;
305  state = PyGILState_Ensure();
306  }
307 
308  PyGILState_Release(state);
309 
310  return result;
311 }
312 
313 QString PythonInterpreter::runScriptOutput(QString _script) {
314  LogOut.clear();
315  LogErr.clear();
316  externalLogging_ = false;
317  runScript(_script);
318  externalLogging_ = true;
319  return LogOut + LogErr;
320 }
321 
322 
323 // Python callback functions
324 void PythonInterpreter::pyOutput(const char* w)
325 {
326  if (externalLogging_) {
327  emit log(LOGOUT, QString(w));
328  } else {
329  LogOut += QString::fromUtf8(w);
330  }
331 }
332 
333 void PythonInterpreter::pyError(const char* w)
334 {
335  if (externalLogging_) {
336  if (OpenFlipper::Options::nogui()) {
337  std::cerr << "Python Error! " << w << std::endl;
338  exit(1);
339  }
340  emit log(LOGERR, QString(w));
341  } else {
342  LogErr += QString::fromUtf8(w);
343  }
344 }
345 
346 
347 
348 
349 PYBIND11_EMBEDDED_MODULE(openflipper, m) {
350 
351  // Export our core. Make sure that the c++ worlds core objet is not deleted if
352  // the python side gets deleted!!
353  py::class_<Core,std::unique_ptr<Core, py::nodelete>> core(m, "Core");
354 
355  // On the c++ side we will just return the existing core instance
356  // and prevent the system to recreate a new core as we need
357  // to work on the existing one.
358  core.def(py::init([]() { return core_; }));
359 
360  core.def("updateView", &Core::updateView, QCoreApplication::translate("PythonDocCore","Redraw the contents of the viewer.").toLatin1().data() );
361  core.def("blockScenegraphUpdates", &Core::blockScenegraphUpdates, QCoreApplication::translate("PythonDocCore","Disable Scenegraph Updates (e.g. before loading or adding a large number of files)").toLatin1().data() );
362  core.def("updateUI", &Core::updateUI, QCoreApplication::translate("PythonDocCore","Process events during script execution to keep the ui alive").toLatin1().data() );
363  core.def("clearAll", &Core::clearAll, QCoreApplication::translate("PythonDocCore","Clear all data objects.").toLatin1().data() );
364  core.def("deleteObject", &Core::deleteObject, QCoreApplication::translate("PythonDocCore","Delete an object from the scene.").toLatin1().data() ,
365  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to delete.").toLatin1().data() ) );
366 
367  core.def("setObjectComment", &Core::setObjectComment, QCoreApplication::translate("PythonDocCore","Add a comment to an object (saved e.g. in screenshot metadata).").toLatin1().data()) ,
368  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to add comment.").toLatin1().data()),
369  py::arg( QCoreApplication::translate("PythonDocCore","Key value").toLatin1().data()),
370  py::arg( QCoreApplication::translate("PythonDocCore","Actual comment").toLatin1().data());
371 
372  core.def("clearObjectComment", &Core::clearObjectComment, QCoreApplication::translate("PythonDocCore","Remove a comment from an object.").toLatin1().data()) ,
373  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to remove comment from.").toLatin1().data()),
374  py::arg( QCoreApplication::translate("PythonDocCore","Key value to remove").toLatin1().data());
375 
376  core.def("clearAllComments", &Core::clearObjectComment, QCoreApplication::translate("PythonDocCore","Remove all comments from an object.").toLatin1().data()) ,
377  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object to remove comments from.").toLatin1().data());
378 
379  core.def("fullscreen", &Core::fullscreen, QCoreApplication::translate("PythonDocCore","Enable or disable fullscreen mode.").toLatin1().data() ,
380  py::arg( QCoreApplication::translate("PythonDocCore","Enable or disable?").toLatin1().data() ) );
381 
382  core.def("showViewModeControls", &Core::deleteObject, QCoreApplication::translate("PythonDocCore","Show or hide the view mode control box").toLatin1().data() ,
383  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
384 
385  core.def("loggerState", &Core::loggerState, QCoreApplication::translate("PythonDocCore","Change the logger window state").toLatin1().data() ,
386  py::arg( QCoreApplication::translate("PythonDocCore","0 = In Scene , 1 = Normal, 2 = Hidden").toLatin1().data() ) );
387 
388  core.def("enableOpenMeshErrorLog", &Core::enableOpenMeshErrorLog, QCoreApplication::translate("PythonDocCore","Enable or disable OpenMesh error logging").toLatin1().data() ,
389  py::arg( QCoreApplication::translate("PythonDocCore","Enable or Disable").toLatin1().data() ) );
390 
391  core.def("showToolbox", &Core::showToolbox, QCoreApplication::translate("PythonDocCore","Show or hide toolbox").toLatin1().data() ,
392  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
393 
394  core.def("showStatusBar", &Core::showStatusBar, QCoreApplication::translate("PythonDocCore","Show or hide status bar").toLatin1().data() ,
395  py::arg( QCoreApplication::translate("PythonDocCore","Visible?").toLatin1().data() ) );
396 
397  core.def("multiViewMode", &Core::multiViewMode, QCoreApplication::translate("PythonDocCore","Switch MultiView Mode").toLatin1().data() ,
398  py::arg( QCoreApplication::translate("PythonDocCore","0: One Viewer, 1: Double Viewer, 2: Grid, 3: Horizontal split").toLatin1().data() ) );
399 
400  core.def("restrictFrameRate", &Core::restrictFrameRate, QCoreApplication::translate("PythonDocCore","Restrict maximal rendering FrameRate to MaxFrameRate").toLatin1().data() ,
401  py::arg( QCoreApplication::translate("PythonDocCore","Restrict Framerate?").toLatin1().data() ) );
402 
403  core.def("setMaxFrameRate", &Core::setMaxFrameRate, QCoreApplication::translate("PythonDocCore","Set the maximal framerate (automatically enables framerate restriction)").toLatin1().data() ,
404  py::arg( QCoreApplication::translate("PythonDocCore","Maximum frameRate").toLatin1().data() ) );
405 
406  core.def("snapshotBaseFileName", &Core::snapshotBaseFileName, QCoreApplication::translate("PythonDocCore","Set a base filename for storing snapshots. This setting is viewer dependent").toLatin1().data() ,
407  py::arg( QCoreApplication::translate("PythonDocCore","Base filename").toLatin1().data()),
408  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the filename for").toLatin1().data() ) );
409 
410  core.def("snapshotFileType", &Core::snapshotFileType, QCoreApplication::translate("PythonDocCore","Set a filetype for storing snapshots.").toLatin1().data() ,
411  py::arg( QCoreApplication::translate("PythonDocCore","Image type as string (e.g. jpg )").toLatin1().data()),
412  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the filetype for").toLatin1().data() ) );
413 
414  core.def("snapshotCounterStart", &Core::snapshotCounterStart, QCoreApplication::translate("PythonDocCore","Set the starting number for the snapshot counter.").toLatin1().data() ,
415  py::arg( QCoreApplication::translate("PythonDocCore","Starting number for the counter").toLatin1().data() ),
416  py::arg( QCoreApplication::translate("PythonDocCore","Viewer ID to set the counter for").toLatin1().data() ) );
417 
418 
419  core.def("snapshot", &Core::snapshot, QCoreApplication::translate("PythonDocCore", "Make a snapshot of the viewer with id viewerId.\n"
420  "Pass 0 as viewerId parameter to capture the current viewer. \n"
421  "The captured image will have the specified dimensions. \n"
422  "If 0 is passed as either width or height parameter, the value will \n"
423  "automatically be set to hold the right aspect ratio, respectively. \n"
424  "If 0 is passed for both width and height values, the viewport's current \n"
425  "dimension is used. Set alpha to true if you want the background to be transparent. \n"
426  "The fifth parameter is used to hide the coordinate system in the upper right corner of the screen. \n"
427  "If no filename was set using snapshotBaseFileName() the snapshot is stored \n"
428  "in snap.png in the current directory. For every snapshot \n"
429  "a counter is added to the filename.").toLatin1().data() ,
430  py::arg( QCoreApplication::translate("PythonDocCore","Id of viewer").toLatin1().data() ) = 0,
431  py::arg( QCoreApplication::translate("PythonDocCore","Width of image").toLatin1().data() )= 0,
432  py::arg( QCoreApplication::translate("PythonDocCore","Height of image").toLatin1().data() )= 0,
433  py::arg( QCoreApplication::translate("PythonDocCore","Transparent background?").toLatin1().data() ) = false,
434  py::arg( QCoreApplication::translate("PythonDocCore","Hide coordinate system?").toLatin1().data() ) = false ,
435  py::arg( QCoreApplication::translate("PythonDocCore","Number of samples per pixel").toLatin1().data() ) =1 );
436 
437 
438  core.def("applicationSnapshot", &Core::applicationSnapshot, QCoreApplication::translate("PythonDocCore","Create a snapshot of the whole application").toLatin1().data() );
439 
440  core.def("applicationSnapshotName", &Core::applicationSnapshotName, QCoreApplication::translate("PythonDocCore","Set the baseName for the application snapshot").toLatin1().data() ,
441  py::arg( QCoreApplication::translate("PythonDocCore","BaseName for full application snapshots").toLatin1().data() ) );
442 
443  core.def("viewerSnapshot", static_cast<void (Core::*)()>(&Core::viewerSnapshot), QCoreApplication::translate("PythonDocCore","Take a snapshot from all viewers").toLatin1().data() );
444 
445  core.def("viewerSnapshot", static_cast<void (Core::*)(QString,bool,bool,bool,bool,int,int,bool,bool,int,bool)>(&Core::viewerSnapshot),
446  QCoreApplication::translate("PythonDocCore","Create a snapshot with full control").toLatin1().data(),
447  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the snapshot").toLatin1().data() ),
448  py::arg( QCoreApplication::translate("PythonDocCore","Should the comments be written?").toLatin1().data() ),
449  py::arg( QCoreApplication::translate("PythonDocCore","Should only the comments of visible objects be written?").toLatin1().data() ),
450  py::arg( QCoreApplication::translate("PythonDocCore","Should only the comments of target objects be written?").toLatin1().data() ),
451  py::arg( QCoreApplication::translate("PythonDocCore","Store material info?").toLatin1().data() ),
452  py::arg( QCoreApplication::translate("PythonDocCore","Snapshot width").toLatin1().data() ),
453  py::arg( QCoreApplication::translate("PythonDocCore","Snapshot height").toLatin1().data() ),
454  py::arg( QCoreApplication::translate("PythonDocCore","Transparent background?").toLatin1().data() ),
455  py::arg( QCoreApplication::translate("PythonDocCore","Hide coordinate system?").toLatin1().data() ),
456  py::arg( QCoreApplication::translate("PythonDocCore","Multisampling count").toLatin1().data() ),
457  py::arg( QCoreApplication::translate("PythonDocCore","Store the view in the metadata?").toLatin1().data() ) );
458 
459 
460  core.def("resizeViewers", &Core::resizeViewers, QCoreApplication::translate("PythonDocCore","Resize the examinerViewer.").toLatin1().data() ,
461  py::arg( QCoreApplication::translate("PythonDocCore","Width").toLatin1().data() ),
462  py::arg( QCoreApplication::translate("PythonDocCore","Height").toLatin1().data() ) );
463 
464  core.def("resizeApplication", &Core::resizeApplication, QCoreApplication::translate("PythonDocCore","Resize the whole Application.").toLatin1().data() ,
465  py::arg( QCoreApplication::translate("PythonDocCore","Width").toLatin1().data() ),
466  py::arg( QCoreApplication::translate("PythonDocCore","Height").toLatin1().data() ) );
467 
468  core.def("writeVersionNumbers", &Core::writeVersionNumbers, QCoreApplication::translate("PythonDocCore","Write the current versions of all plugins to ini file").toLatin1().data() ,
469  py::arg( QCoreApplication::translate("PythonDocCore","Full path to a file where the versions should be written to.").toLatin1().data() ) );
470 
471 // core.def("objectList", &Core::objectList, QCoreApplication::translate("PythonDocCore","Return an id list of available object that has the given selection and type").toLatin1().data() ,
472 // py::arg( QCoreApplication::translate("PythonDocCore","Either source or target").toLatin1().data()) ,
473 // py::arg( QCoreApplication::translate("PythonDocCore","Object types as a stringlist").toLatin1().data() ));
474 
475 // /// return the list of available object that has the given selection and type
476 // QList<int> objectList (QString _selection, QStringList _types);
477 
478  core.def("blockSceneGraphUpdates", &Core::blockSceneGraphUpdates, QCoreApplication::translate("PythonDocCore","Block the scenegraph updates for improved performance").toLatin1().data() );
479  core.def("unblockSceneGraphUpdates", &Core::unblockSceneGraphUpdates, QCoreApplication::translate("PythonDocCore","Unblock the scenegraph updates").toLatin1().data() );
480 
481 
482  core.def("setView", &Core::setView, QCoreApplication::translate("PythonDocCore","Set the encoded view for the primary viewport.").toLatin1().data() ,
483  py::arg( QCoreApplication::translate("PythonDocCore","The encoded view. (You can obtain one through \"Copy View\" in the context menu of the coordinates.)").toLatin1().data() ) );
484 
485  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() ,
486  py::arg( QCoreApplication::translate("PythonDocCore","The encoded view. (You can obtain one through \"Copy View\" in the context menu of the coordinates.)").toLatin1().data() ) );
487 
488  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() ,
489  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
490  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of toolboxes visible in this viewmode)").toLatin1().data() ));
491 
492  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() ,
493  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
494  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of toolbars visible in this viewmode)").toLatin1().data() ));
495 
496  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() ,
497  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
498  py::arg( QCoreApplication::translate("PythonDocCore","';' separated list of Context Menus visible in this viewmode)").toLatin1().data() ));
499 
500  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() ,
501  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Viewmode").toLatin1().data() ),
502  py::arg( QCoreApplication::translate("PythonDocCore","filename of the icon (will be taken from OpenFlippers icon directory)").toLatin1().data() ));
503 
504 
505  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() ,
506  py::arg( QCoreApplication::translate("PythonDocCore","The desired side of the toolboxes (either 'left' or 'right')").toLatin1().data() ) );
507 
508  core.def("setToolBoxActive", &Core::setToolBoxActive, QCoreApplication::translate("PythonDocCore","Activate or deaktivate a toolbox").toLatin1().data() ,
509  py::arg( QCoreApplication::translate("PythonDocCore","Name of the toolbox.").toLatin1().data() ),
510  py::arg( QCoreApplication::translate("PythonDocCore","Activate or deaktivate?").toLatin1().data() ));
511 
512  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() ,
513  py::arg( QCoreApplication::translate("PythonDocCore","Filename to load.").toLatin1().data() ) );
514 
515  core.def("startVideoCapture", &Core::startVideoCapture, QCoreApplication::translate("PythonDocCore","Start video capturing.").toLatin1().data() ,
516  py::arg( QCoreApplication::translate("PythonDocCore","Basename for capturing").toLatin1().data() ),
517  py::arg( QCoreApplication::translate("PythonDocCore","Frames per second").toLatin1().data() ),
518  py::arg( QCoreApplication::translate("PythonDocCore","Should the viewers be captured or the whole application?").toLatin1().data() ) );
519 
520  core.def("stopVideoCapture", &Core::stopVideoCapture, QCoreApplication::translate("PythonDocCore","Stop video capturing").toLatin1().data() );
521 
522  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() ,
523  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object)").toLatin1().data() ),
524  py::arg( QCoreApplication::translate("PythonDocCore","Complete path and filename").toLatin1().data() ));
525 
526  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() ,
527  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object)").toLatin1().data() ),
528  py::arg( QCoreApplication::translate("PythonDocCore","Initial filename in the dialog").toLatin1().data() ));
529 
530 
531 // bool saveObjectsTo( IdList _ids, QString _filename );
532 
533 
534  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() );
535 
536  core.def("saveAllObjectsTo", &Core::saveAllObjectsTo, QCoreApplication::translate("PythonDocCore","Saves all target objects. The locations can be chosen in dialogs. (Only GUI Mode!)").toLatin1().data() );
537 
538  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() );
539 
540  core.def("saveSettings", static_cast<void (Core::*)(QString,bool,bool,bool,bool,bool,bool)>(&Core::saveSettings),
541  QCoreApplication::translate("PythonDocCore","Save the current setting to the given file.").toLatin1().data(),
542  py::arg( QCoreApplication::translate("PythonDocCore","Path of the file to save the settings to.").toLatin1().data() ),
543  py::arg( QCoreApplication::translate("PythonDocCore","Save Object information into file?").toLatin1().data() ),
544  py::arg( QCoreApplication::translate("PythonDocCore","Restrict to targeted objects?").toLatin1().data() ),
545  py::arg( QCoreApplication::translate("PythonDocCore","Save objects into same path as settings file?").toLatin1().data() ),
546  py::arg( QCoreApplication::translate("PythonDocCore","Prompt before overwriting files that already exist (gui mode only).").toLatin1().data() ),
547  py::arg( QCoreApplication::translate("PythonDocCore","Save program settings?").toLatin1().data() ),
548  py::arg( QCoreApplication::translate("PythonDocCore","Save plugin settings?").toLatin1().data() ) );
549 
550  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() );
551 
552  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() );
553 
554  core.def("loadSettings", static_cast<void (Core::*)(QString)>(&Core::loadSettings), QCoreApplication::translate("PythonDocCore","Load settings from file.").toLatin1().data() ,
555  py::arg( QCoreApplication::translate("PythonDocCore","Filename to load.").toLatin1().data() ) );
556 
557  core.def("getObjectId", &Core::getObjectId, QCoreApplication::translate("PythonDocCore","Return identifier of object with specified name. Returns -1 if object was not found.").toLatin1().data() ,
558  py::arg( QCoreApplication::translate("PythonDocCore","Filename or name of the object").toLatin1().data() ) );
559 
560  core.def("deserializeMaterialProperties", &Core::deserializeMaterialProperties, QCoreApplication::translate("PythonDocCore","Deserialize the supplied material properties into the supplied object.").toLatin1().data() ,
561  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object").toLatin1().data() ),
562  py::arg( QCoreApplication::translate("PythonDocCore","Material properties encoded as string").toLatin1().data() ) );
563 
564  core.def("serializeMaterialProperties", &Core::serializeMaterialProperties, QCoreApplication::translate("PythonDocCore","Serialize and return the material properties of the supplied object.").toLatin1().data() ,
565  py::arg( QCoreApplication::translate("PythonDocCore","Id of the object").toLatin1().data() ));
566 
567  core.def("activateToolbox", &Core::activateToolbox, QCoreApplication::translate("PythonDocCore","Expand or collapse a toolbox").toLatin1().data() ,
568  py::arg( QCoreApplication::translate("PythonDocCore","Name of the plugin to which this toolbox gelongs").toLatin1().data() ),
569  py::arg( QCoreApplication::translate("PythonDocCore","Name of the toolbox").toLatin1().data() ),
570  py::arg( QCoreApplication::translate("PythonDocCore","Expand or collapse?").toLatin1().data() ) );
571 
572  core.def("saveOptions", &Core::saveOptions, QCoreApplication::translate("PythonDocCore","Save the current options to the standard ini file").toLatin1().data() );
573 
574  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() );
575 
576  core.def("openIniFile", &Core::openIniFile, QCoreApplication::translate("PythonDocCore","Load information from an ini file").toLatin1().data() ,
577  py::arg( QCoreApplication::translate("PythonDocCore","Name of the ini file").toLatin1().data() ),
578  py::arg( QCoreApplication::translate("PythonDocCore","Load applications settings?").toLatin1().data() ),
579  py::arg( QCoreApplication::translate("PythonDocCore","Load plugin settings?").toLatin1().data() ),
580  py::arg( QCoreApplication::translate("PythonDocCore"," Load objects defined in the ini file?").toLatin1().data() ));
581 
582 
583 // /** \brief Create an script object from a ui file
584 // *
585 // * This function will load an ui file, set up a qwidget from that and makes it available
586 // * under _objectName for scripting.
587 // * @param _objectName The name in scripting environment used for the new object
588 // * @param _uiFilename ui file to load
589 // */
590 // void createWidget(QString _objectName, QString _uiFilename, bool _show = true);
591 
592  core.def("setViewMode", &Core::setViewMode, QCoreApplication::translate("PythonDocCore","Switch to the given viewmode").toLatin1().data() ,
593  py::arg( QCoreApplication::translate("PythonDocCore","Name of the viewmode to enable").toLatin1().data() ) );
594 
595 
596  core.def("getCurrentViewMode", &Core::getCurrentViewMode, QCoreApplication::translate("PythonDocCore","Get the name of the current viewMode").toLatin1().data() );
597 
598  core.def("setViewModeIcon", &Core::setViewModeIcon, QCoreApplication::translate("PythonDocCore","Set an icon for a view Mode").toLatin1().data() ,
599  py::arg( QCoreApplication::translate("PythonDocCore","Name of the mode for the icon").toLatin1().data() ),
600  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the icon").toLatin1().data() ) );
601 
602  core.def("moveToolBoxToTop", &Core::moveToolBoxToTop, QCoreApplication::translate("PythonDocCore","Move selected toolbox to the top of side area").toLatin1().data() ,
603  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Toolbox to be moved").toLatin1().data() ) );
604 
605  core.def("moveToolBoxToBottom", &Core::moveToolBoxToBottom, QCoreApplication::translate("PythonDocCore","Move selected toolbox to the bottom of side area").toLatin1().data() ,
606  py::arg( QCoreApplication::translate("PythonDocCore","Name of the Toolbox to be moved").toLatin1().data() ) );
607 
608  core.def("showReducedMenuBar", &Core::showReducedMenuBar, QCoreApplication::translate("PythonDocCore","Show only a reduced menubar").toLatin1().data() ,
609  py::arg( QCoreApplication::translate("PythonDocCore","Reduced Menubar?").toLatin1().data() ) );
610 
611  core.def("executePythonScriptFile", &Core::executePythonScriptFile, QCoreApplication::translate("PythonDocCore","Open the given file and execute its contents as a python script").toLatin1().data() ,
612  py::arg( QCoreApplication::translate("PythonDocCore","Filename of the script").toLatin1().data() ) );
613 
614 
615  core.def("executePythonScript", &Core::executePythonScript, QCoreApplication::translate("PythonDocCore","Execute a text as a python script").toLatin1().data() ,
616  py::arg( QCoreApplication::translate("PythonDocCore","The text of the script").toLatin1().data() ) );
617 
618  core.def("exitApplication", &Core::exitApplication, QCoreApplication::translate("PythonDocCore","Exit the application").toLatin1().data() );
619  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() );
620  core.def("finishSplash", &Core::finishSplash, QCoreApplication::translate("PythonDocCore","Hide the splash screen").toLatin1().data() );
621 
622  core.def("objectUpdated", &Core::slotObjectUpdated, QCoreApplication::translate("PythonDocCore","Tell the core that an object has been updated").toLatin1().data(),
623  py::arg( QCoreApplication::translate("PythonDocCore","ID of the updated object").toLatin1().data() ),
624  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 );
625 
626 
627 // //load slots
628 // emit setSlotDescription("createWidget(QString,QString)", tr("Create a widget from an ui file"),
629 // QString(tr("Object name,ui file")).split(","),
630 // QString(tr("Name of the new widget in script,ui file to load")).split(","));
631 
632 // emit setSlotDescription("objectList(QString,QStringList)", tr("Returns object list"),
633 // QString(tr("Selection type,Object types")).split(","),
634 
635 
636 
637 
638 }
639 
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:1270
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:1045
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:1473
void showStatusBar(bool _state)
Show or hide Status Bar.
Definition: Core.cc:1126
void showToolbox(bool _state)
Show or hide toolbox.
Definition: Core.cc:1119
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:1070
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:1817
void deleteObject(int _id)
Called to delete an object.
Definition: Core.cc:1788
void setMaxFrameRate(int _rate)
set the maximal framerate ( automatically enables framerate restriction )
Definition: Core.cc:1034
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:996
void resizeViewers(int _width, int _height)
resize the examinerViewer
Definition: Core.cc:1546
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:1500
void resizeApplication(int _width, int _height)
resize the whole Application
Definition: Core.cc:1557
void loggerState(int _state)
Change the logging window state.
Definition: Core.cc:1085
void exitApplication()
exit the current application
Definition: Core.cc:1058
void multiViewMode(int _mode)
Switch the multiView Mode.
Definition: Core.cc:1133
void enableOpenMeshErrorLog(bool _state)
Enable or disable OpenMesh error logging.
Definition: Core.cc:1096
void snapshotCounterStart(const int _counter, unsigned int _viewerId=0)
Set the start index for the snapshot counter.
Definition: Core.cc:1487
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:945
void snapshotBaseFileName(QString _fname, unsigned int _viewerId=0)
Definition: Core.cc:1460
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:1519
void pyError(const char *w)
Callback to redirect cerr log to OpenFlipper logger.
void showReducedMenuBar(bool reduced)
Core scripting engine.
Definition: Core.cc:2061
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:2065
void blockScenegraphUpdates(bool _block)
Called when a plugin wants to lock or unlock scenegraph updates.
Definition: Core.cc:1002
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:1836
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:1525
void clearObjectComment(int objId, QString key)
Called when a plugin requests an update in the viewer.
Definition: Core.cc:1869
void restrictFrameRate(bool _enable)
Enable or disable framerate restriction.
Definition: Core.cc:1028
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:1856
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:1513
void writeVersionNumbers(QString _filename)
write the current versions of all plugins to ini file
Definition: Core.cc:1567
void stopVideoCapture()
Stop video capturing.
Definition: Video.cc:109
void initPython()
Initialize OpenFlipper Python Interpreter.