[Bf-blender-cvs] [a50c131a0d7] blender-v2.83-release: Fix T75889: Cannot bake mantaflow via Python API

Jacques Lucke noreply at git.blender.org
Tue May 12 12:18:23 CEST 2020


Commit: a50c131a0d71d04915cc39c5a412f4f16c6f706b
Author: Jacques Lucke
Date:   Tue May 12 12:12:21 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rBa50c131a0d71d04915cc39c5a412f4f16c6f706b

Fix T75889: Cannot bake mantaflow via Python API

The issue was the usage of the global `__main__` Python module.
When running scripts in the text editor, Blender would overwrite
the `__main__` module.

Reviewers: sebbas

Differential Revision: https://developer.blender.org/D7690

===================================================================

M	intern/mantaflow/intern/MANTA_main.cpp

===================================================================

diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp
index 56d4c51df86..35d4629d195 100644
--- a/intern/mantaflow/intern/MANTA_main.cpp
+++ b/intern/mantaflow/intern/MANTA_main.cpp
@@ -538,19 +538,49 @@ MANTA::~MANTA()
   (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(std::vector<std::string> commands)
 {
-  int success = -1;
+  bool success = true;
   PyGILState_STATE gilstate = PyGILState_Ensure();
+
+  if (manta_main_module == nullptr) {
+    manta_main_module = PyImport_ImportModule("__main__");
+  }
+
   for (std::vector<std::string>::iterator it = commands.begin(); it != commands.end(); ++it) {
     std::string command = *it;
-    success = PyRun_SimpleString(command.c_str());
+
+    PyObject *globals_dict = PyModule_GetDict(manta_main_module);
+    PyObject *return_value = PyRun_String(
+        command.c_str(), Py_file_input, globals_dict, globals_dict);
+
+    if (return_value == nullptr) {
+      success = false;
+      if (PyErr_Occurred()) {
+        PyErr_Print();
+      }
+    }
+    else {
+      Py_DECREF(return_value);
+    }
   }
   PyGILState_Release(gilstate);
 
-  /* PyRun_SimpleString returns 0 on success, -1 when an error occurred. */
-  assert(success == 0);
-  return (success != -1);
+  assert(success);
+  return success;
 }
 
 void MANTA::initializeMantaflow()
@@ -2124,19 +2154,18 @@ static PyObject *callPythonFunction(std::string varName,
   }
 
   PyGILState_STATE gilstate = PyGILState_Ensure();
-  PyObject *main = nullptr, *var = nullptr, *func = nullptr, *returnedValue = nullptr;
+  PyObject *var = nullptr, *func = nullptr, *returnedValue = nullptr;
 
-  /* Be sure to initialise Python before importing main. */
+  /* Be sure to initialize Python before using it. */
   Py_Initialize();
 
   // Get pyobject that holds result value
-  main = PyImport_ImportModule("__main__");
-  if (!main) {
+  if (!manta_main_module) {
     PyGILState_Release(gilstate);
     return nullptr;
   }
 
-  var = PyObject_GetAttrString(main, varName.c_str());
+  var = PyObject_GetAttrString(manta_main_module, varName.c_str());
   if (!var) {
     PyGILState_Release(gilstate);
     return nullptr;



More information about the Bf-blender-cvs mailing list