diff --git a/bindings/python/pinocchio/__init__.py b/bindings/python/pinocchio/__init__.py index 1354d404a4..7191711ba0 100644 --- a/bindings/python/pinocchio/__init__.py +++ b/bindings/python/pinocchio/__init__.py @@ -3,7 +3,44 @@ # import numpy -from .pinocchio_pywrap import * + +# On Windows, if pinocchio.dll is not in the same directory than +# the .pyd, it will not be loaded. +# We first try to load pinocchio, then, if it fail and we are on Windows: +# 1. We add all paths inside PINOCCHIO_WINDOWS_DLL_PATH to DllDirectory +# 2. If PINOCCHIO_WINDOWS_DLL_PATH we add the relative path from the +# package directory to the bin directory to DllDirectory +# This solution is inspired from: +# - https://github.com/PixarAnimationStudios/OpenUSD/pull/1511/files +# - https://stackoverflow.com/questions/65334494/python-c-extension-packaging-dll-along-with-pyd +# More resources on https://github.com/diffpy/pyobjcryst/issues/33 +try: + from .pinocchio_pywrap import * +except ImportError: + import os + import sys + import platform + if platform.system() == "Windows": + __pinocchio_paths = os.getenv('PINOCCHIO_WINDOWS_DLL_PATH') + if __pinocchio_paths is None: + # Standard site-packages to bin path + RELATIVE_DLL_PATH = "..\\..\\..\\bin" + __dll_paths = [os.path.join(os.path.dirname(__file__), RELATIVE_DLL_PATH)] + else: + __dll_paths = __pinocchio_paths.split(os.pathsep) + if sys.version_info >= (3, 8): + for p in __dll_paths: + # add_dll_directory can fail on relative path and non + # existing path. + # Since we don't know all the fail criterion we just ignore + # thrown exception + try: + os.add_dll_directory(p) + except OSError: + pass + else: + for p in __dll_paths: + os.environ["PATH"] += os.pathsep + p from .pinocchio_pywrap import __version__, __raw_version__