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