Changeset View
Changeset View
Standalone View
Standalone View
intern/mantaflow/intern/MANTA_main.cpp
| Show First 20 Lines • Show All 546 Lines • ▼ Show 20 Lines | MANTA::~MANTA() | ||||
| string finalString = parseScript(tmpString); | string finalString = parseScript(tmpString); | ||||
| pythonCommands.push_back(finalString); | pythonCommands.push_back(finalString); | ||||
| result = runPythonString(pythonCommands); | result = runPythonString(pythonCommands); | ||||
| assert(result); | assert(result); | ||||
| (void)result; // not needed in release | (void)result; // not needed in release | ||||
| } | } | ||||
| /** | |||||
| * Store a pointer to the __main__ module used by mantaflow. This is necessary, because sometimes | |||||
| * Blender will overwrite that module. That happens when e.g. scripts are executed in the text | |||||
| * editor. | |||||
| * | |||||
| * Mantaflow stores many variables in the globals() dict of the __main__ module. To be able to | |||||
| * access these variables, the same __main__ module has to be used every time. | |||||
| * | |||||
| * Unfortunately, we also depend on the fact that mantaflow dumps variables into this module using | |||||
| * PyRun_SimpleString. So we can't easily create a separate module without changing mantaflow. | |||||
| */ | |||||
| static PyObject *manta_main_module = nullptr; | |||||
| bool MANTA::runPythonString(vector<string> commands) | bool MANTA::runPythonString(vector<string> commands) | ||||
| { | { | ||||
| int success = -1; | bool success = true; | ||||
| PyGILState_STATE gilstate = PyGILState_Ensure(); | PyGILState_STATE gilstate = PyGILState_Ensure(); | ||||
| if (manta_main_module == nullptr) { | |||||
| manta_main_module = PyImport_ImportModule("__main__"); | |||||
| } | |||||
| for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) { | for (vector<string>::iterator it = commands.begin(); it != commands.end(); ++it) { | ||||
| string command = *it; | string command = *it; | ||||
| PyObject *globals_dict = PyModule_GetDict(manta_main_module); | |||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| // special treatment for windows when running python code | // special treatment for windows when running python code | ||||
JacquesLucke: @sebbas Do you remember why this special treatment is necessary? I don't see the need for it. | |||||
sebbasUnsubmitted Not Done Inline ActionsNo, not sure ... I guess you've already tried building without the ifdef on Windows and it's not problematic? In that case, I would remove it and watch out for it. sebbas: No, not sure ... I guess you've already tried building without the `ifdef` on Windows and it's… | |||||
JacquesLuckeAuthorUnsubmitted Done Inline ActionsNo, I haven't. Will do tomorrow. I'll commit this cleanup separately if it works on windows. JacquesLucke: No, I haven't. Will do tomorrow.
I'll commit this cleanup separately if it works on windows. | |||||
| size_t cmdLength = command.length(); | size_t cmdLength = command.length(); | ||||
| char *buffer = new char[cmdLength + 1]; | char *buffer = new char[cmdLength + 1]; | ||||
| memcpy(buffer, command.data(), cmdLength); | memcpy(buffer, command.data(), cmdLength); | ||||
| buffer[cmdLength] = '\0'; | buffer[cmdLength] = '\0'; | ||||
| success = PyRun_SimpleString(buffer); | PyObject *value = PyRun_String(buffer, Py_file_input, globals_dict, globals_dict); | ||||
| delete[] buffer; | delete[] buffer; | ||||
| #else | #else | ||||
| success = PyRun_SimpleString(command.c_str()); | PyObject *value = PyRun_String(command.c_str(), Py_file_input, globals_dict, globals_dict); | ||||
| #endif | #endif | ||||
| if (value == nullptr) { | |||||
| success = false; | |||||
| if (PyErr_Occurred()) { | |||||
| PyErr_Print(); | |||||
| } | |||||
| } | |||||
| else { | |||||
| Py_DECREF(value); | |||||
| } | |||||
| } | } | ||||
| PyGILState_Release(gilstate); | PyGILState_Release(gilstate); | ||||
| /* PyRun_SimpleString returns 0 on success, -1 when an error occurred. */ | assert(success); | ||||
| assert(success == 0); | return success; | ||||
| return (success != -1); | |||||
| } | } | ||||
| void MANTA::initializeMantaflow() | void MANTA::initializeMantaflow() | ||||
| { | { | ||||
| if (with_debug) | if (with_debug) | ||||
| cout << "Fluid: Initializing Mantaflow framework" << endl; | cout << "Fluid: Initializing Mantaflow framework" << endl; | ||||
| string filename = "manta_scene_" + to_string(mCurrentID) + ".py"; | string filename = "manta_scene_" + to_string(mCurrentID) + ".py"; | ||||
| ▲ Show 20 Lines • Show All 1,401 Lines • ▼ Show 20 Lines | static PyObject *callPythonFunction(string varName, string functionName, bool isAttribute = false) | ||||
| PyGILState_STATE gilstate = PyGILState_Ensure(); | PyGILState_STATE gilstate = PyGILState_Ensure(); | ||||
| PyObject *main = nullptr, *var = nullptr, *func = nullptr, *returnedValue = nullptr; | PyObject *main = nullptr, *var = nullptr, *func = nullptr, *returnedValue = nullptr; | ||||
| /* Be sure to initialise Python before importing main. */ | /* Be sure to initialise Python before importing main. */ | ||||
| Py_Initialize(); | Py_Initialize(); | ||||
| // Get pyobject that holds result value | // Get pyobject that holds result value | ||||
| main = PyImport_ImportModule("__main__"); | main = manta_main_module; | ||||
| if (!main) { | if (!main) { | ||||
| PyGILState_Release(gilstate); | PyGILState_Release(gilstate); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| var = PyObject_GetAttrString(main, varName.c_str()); | var = PyObject_GetAttrString(main, varName.c_str()); | ||||
| if (!var) { | if (!var) { | ||||
| PyGILState_Release(gilstate); | PyGILState_Release(gilstate); | ||||
| ▲ Show 20 Lines • Show All 1,124 Lines • Show Last 20 Lines | |||||
@Sebastián Barschkis (sebbas) Do you remember why this special treatment is necessary? I don't see the need for it.