TL;DR
Hello, I’m using Blender as a Python module to automate the exportation of fbx files directly from Unity Editor. So far I’ve managed to put all the pieces together and I’m able to generate fbx files, but whenever Unity reloads the .net assemblies Google Logging library used by blender enters on an invalid state and eventually crashes.
Here is the log it generates before crashing:
Could not create logging file: Invalid argument
COULD NOT CREATE A LOGGINGFILE 20200521-153632.181824!Could not create logging file: Invalid argument
COULD NOT CREATE A LOGGINGFILE 20200521-153632.181824!Could not create logging file: Invalid argument
COULD NOT CREATE A LOGGINGFILE 20200521-153632.181824!Could not create logging file: Invalid argument
COULD NOT CREATE A LOGGINGFILE 20200521-153632.181824!F0521 15:36:32.549110 149480 utilities.cc:322] Check failed: !IsGoogleLoggingInitialized() You called InitGoogleLogging() twice!
*** Check failure stack trace: ***
Context
I have compiled Blender from branch blender-v2.82-release as a Python module and added it to an embedded Python on Unity Editor through Python.NET. I can access bpy
from the Unity Editor.
I’ve had python running on Unity for quite a while now so I’m positive that the problem is directly related to adding the blender module to the equation.
Assembly Reloading
On the Unity Editor whenever there is a change in the c# script files Unity will recompile the .net assemblies, unload the old assemblies and then load the newly compiled assemblies.
Project File Structure
I chose to keep blender files in a separated folder to make it easy to track blender files from python files. During python initialization I add the proper folders to python_path and I also set the BLENDER_SYSTEM_SCRIPTS and BLENDER_SYSTEM_DATAFILES environment variables to the appropriate directories.
Project folder (cwd)
|- Tools
|- Python
| |- Lib/site-packages
| |- python37.zip
|- Blender
|- 2.82
| |- datafiles
| |- scripts
|- bpy.pyd
|- BlendThumb.dll
|- tbbmalloc.dll
|- tbbmalloc_proxy.dll
Pyhton Initialization Inside Unity
The following script is showing how I initialize and shutdown python from Unity. I also have to shutdown and re-initialize Python when the unity assemblies are reloaded. As the .net code I’m using is a wrapper around python37.dll I annotated the code with comments pointing to the relevant native calls to the python37.dll made by the .net wrapper.
[InitializeOnLoadMethod]
static void Initialize()
{
AssemblyReloadEvents.beforeAssemblyReload += ShutdownPythonEngine;
AssemblyReloadEvents.afterAssemblyReload += InitializePythonEngine;
EditorApplication.quitting += ShutdownPythonEngine;
}
// called when Unity is open or assemblies are reload
static void InitializePythonEngine()
{
Debug.Log("Initializing Python Engine...");
var projectPath = Path.GetFullPath($@"{Application.dataPath}\..");
var toolsPath = $@"{projectPath}\Tools";
var logsPath = $@"{projectPath}\Logs\{Guid.NewGuid()}";
var pythonHome = $@"{toolsPath}\Python";
var blenderHome = $@"{toolsPath}\Blender";
PythonEngine.PythonHome = pythonHome;
var pythonLib = $@"{pythonHome}\Lib";
var pythonSitePackages = $@"{pythonHome}\Lib\site-packages";
var pythonZip = $@"{pythonHome}\python37.zip";
PythonEngine.PythonPath = $"{pythonZip};{pythonHome};{pythonLib};{pythonSitePackages};{blenderHome}";
// set necessary blender environment variables
Environment.SetEnvironmentVariable("BLENDER_SYSTEM_SCRIPTS", $@"{blenderHome}\2.82\scripts");
Environment.SetEnvironmentVariable("BLENDER_SYSTEM_DATAFILES", $@"{blenderHome}\2.82\datafiles");
//Environment.SetEnvironmentVariable("GLOG_log_dir", logsPath);
PythonEngine.Initialize(); // loads python37.dll and initialize Python
_threadsPtr = PythonEngine.BeginAllowThreads(); // Calls PyEval_SaveThread
}
// called when Unity is closed or before assemblies are reload
static void ShutdownPythonEngine()
{
Debug.Log("Shutting Down Python Engine...");
PythonEngine.EndAllowThreads(_threadsPtr); // calls PyEval_RestoreThread
PythonEngine.Shutdown(); // calls Py_Finalize
}
What I’ve done so far
I’ve done some digging in the blender source code and found that this error message is raised by the InitGoogleLoggingUtilities
function on utilities.cc line 321 and there is also a ShutdownGoogleLoggingUtilities
defined at line 337 of the same file that should be called on shutdown.
I’ve notticed that the InitGoogleLoggingUtilities
is indirectly called by the libmv_initLogging
function on logging.cc line 36 during initialization but I did not find any call to ShutdownGoogleLoggingUtilities
on the code.
I believe that the error I’m getting is due to ShutdownGoogleLoggingUtilities
not being called when bpy module is shutdown.
Does it make sense? If so, can this be fixed for future versions?
Also, since I’m using an earlier version of blender, what can I do to fix the problem on my end? Should I try and fix the code myself or there is anything else that can be done?