Closed tsvilans closed 5 years ago
Hi @jesterKing , tried to make a PR for the dependencies stuff and realized an older one was still open. Take a look and comment when you have a free moment...
Thanks, I'll check them when at my machine later today.
Oh! This one slipped my attention. As said, I'll check it later today. Thank you for the reminder, and sorry I forgot
With a fresh Blender build on Linux the dependency install isn't working yet. Investigating.
@tsvilans I have been trying to get this to work on my linux box as well. I got as far as having the pip dependency installed, but the pip install of rhino3dm fails.
The error that persists is:
Could not install packages due to an EnvironmentError: [Errno 2] No such file or directory: '/tmp/pip-req-tracker-m_hc2_0n/bcfbd6ee60f98835718df79377a8340417530d1465879ee428765018'
This is the patch sofar. It improves the way pip dependency is satisfied so that it works at least also on my Linux box. - please review and apply the changes that also work still on your machine:
index b3cdfd9..ea92404 100644
--- a/import_3dm/read3dm.py
+++ b/import_3dm/read3dm.py
@@ -24,27 +24,44 @@ import os.path
import bpy
def install_dependencies():
+ import sys
+ import os
try:
try:
import pip
except:
from subprocess import call
print("Installing pip... "),
- res = call("{} -m ensurepip".format(bpy.app.binary_path_python))
+ ensurepip = os.path.normpath(
+ os.path.join(
+ os.path.dirname(bpy.app.binary_path_python),
+ "../lib/python{}.{}/ensurepip".format(
+ sys.version_info.major,
+ sys.version_info.minor)
+ )
+ )
+ res = call(bpy.app.binary_path_python, ensurepip)
if res == 0:
import pip
else:
raise Exception("Failed to install pip.")
- print("Installing rhino3dm... "),
+ modulespath = os.path.normpath(
+ os.path.join(
+ bpy.utils.script_path_user(),
+ "addons/modules"
+ )
+ if not os.path.exists(modulespath):
+ os.makedirs(modulespath)
+ print("Installing rhino3dm to {}... ".format(modulespath)),
try:
from pip import main as pipmain
except:
from pip._internal import main as pipmain
- res = pipmain(["install", "rhino3dm"])
+ res = pipmain(["install", "--upgrade", "--target", modulespath, "rhino3dm"])
if res > 0:
raise Exception("Failed to install rhino3dm.")
except:
I just realise that in my code the os.sep should probably be used instead of forward slash.
Hey @jesterKing , did you try running Blender with administrator privileges? I noticed I needed those to install anything via pip
through Blender.
Then again... that whole thing must be different on Linux... I have very limited LInux knowledge :/
index b3cdfd9..ea92404 100644 --- a/import_3dm/read3dm.py +++ b/import_3dm/read3dm.py @@ -24,27 +24,44 @@ import os.path import bpy def install_dependencies(): + import sys + import os try: try: import pip except: from subprocess import call print("Installing pip... "), - res = call("{} -m ensurepip".format(bpy.app.binary_path_python)) + ensurepip = os.path.normpath( + os.path.join( + os.path.dirname(bpy.app.binary_path_python), + "../lib/python{}.{}/ensurepip".format( + sys.version_info.major, + sys.version_info.minor) + ) + )
This expands to something liketh 2.80/python/lib/python3.7/ensurepip
. On Windows, there is no python3.7
folder or similar.. the libs
folder contains ensurepip
directly. Should we put an OS check?
res = call(bpy.app.binary_path_python, ensurepip) if res == 0: import pip else: raise Exception("Failed to install pip.") - print("Installing rhino3dm... "), + modulespath = os.path.normpath( + os.path.join( + bpy.utils.script_path_user(), + "addons/modules" + ) + if not os.path.exists(modulespath): + os.makedirs(modulespath) + print("Installing rhino3dm to {}... ".format(modulespath)),
This is so that rhino3dm
gets installed to a separate modules directory? I wasn't aware of that, I thought it always just went into the site-packages
folder in the Python dir. Nice!
I just realise that in my code the os.sep should probably be used instead of forward slash.
os.path.join
takes a list too, so you could just do:
os.path.join( os.path.dirname(bpy.app.binary_path_python), "..", "lib", "python{}.{}".format( sys.version_info.major, sys.version_info.minor), "ensurepip" )
@tsvilans it is not necessary to run Blender with elevated access on Linux. The changes I propose also try to install in the user add-ons folder, which is either under %APPDATA% or under .config/, which is all writable by the user (or should be anyway).
I haven't managed to find a fix for the problem with the pip install command from Blender. On the command-line it all worked correctly.
@tsvilans it is not necessary to run Blender with elevated access on Linux. The changes I propose also try to install in the user add-ons folder, which is either under %APPDATA% or under .config/, which is all writable by the user (or should be anyway).
I haven't managed to find a fix for the problem with the pip install command from Blender. On the command-line it all worked correctly.
@jesterKing Yeah, installing to the user add-ons / modules folder sounds much better. Good to keep extra modules separate from the Blender Python stuff.
Regarding the pip install
problem, is this still only on Linux?
I found some links to similar problems:
dist-info
folder before installing: https://github.com/googleapis/google-cloud-python/issues/6647#issuecomment-462816835METADATA
file into the right directory: https://stackoverflow.com/questions/54778630/could-not-install-packages-due-to-an-environmenterror-errno-2-no-such-file-orwhich is either under %APPDATA% or under .config/, which is all writable by the user (or should be anyway).
@jesterKing Also, do you know if this is stored in Blender somewhere? If there was a variable similar to bpy.app.binary_path_python
- something like bpy.app.user_data_directory
- that would be safer.
which is either under %APPDATA% or under .config/, which is all writable by the user (or should be anyway).
@jesterKing Also, do you know if this is stored in Blender somewhere? If there was a variable similar to
bpy.app.binary_path_python
- something likebpy.app.user_data_directory
- that would be safer.
@jesterKing found it: bpy.utils.resource_path('USER')
-> C:\\Users\\tsvi\\AppData\\Roaming\\Blender Foundation\\Blender\\2.80
Or even better: bpy.utils.script_path_user()
-> C:\\Users\\tsvi\\AppData\\Roaming\\Blender Foundation\\Blender\\2.80\\scripts
Sorry for spamming you this morning...
@jesterKing found it:
bpy.utils.resource_path('USER')
I used bpy.utils.script_path_user()
in my diff. I suppose resource_path('USER')
works too, maybe they even translate to the same.
I found some links to similar problems
Thanks, going through them.
I used bpy.utils.script_path_user() in my diff. I suppose resource_path('USER') works too, maybe they even translate to the same.
My bad, I didn't catch this. Yep, you're already using the right one. Sorry!
To get this forward and finally merged, could you please put the automatic dependency installation code behind a platform specific check? For now it should be ok to have that only on Windows, where there is probably the most benefit gained anyway.
@jesterKing Ok, that should hopefully do it..
Does your patch get added in as well?
@tsvilans I am trying to get it to run, but on my windows box I see this error:
res = call(bpy.app.binary_path_python, ensurepip) Traceback (most recent call last): File "
", line 1, in File "C:\Users\Nathan\PortableApps\blender-2.80-windows64\2.80\python\lib\subprocess.py", line 304, in call with Popen(*popenargs, **kwargs) as p: File "C:\Users\Nathan\PortableApps\blender-2.80-windows64\2.80\python\lib\subprocess.py", line 658, in init raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer
FWIW the current patch for read3dm.py I am working with is
@@ -22,31 +22,55 @@
import os.path
import bpy
def install_dependencies():
+ import sys
+ import os
try:
try:
import pip
except:
from subprocess import call
print("Installing pip... "),
- res = call("{} -m ensurepip".format(bpy.app.binary_path_python))
+ pyver = ""
+ if sys.platform != "win32":
+ pyver = "python{}.{}".format(
+ sys.version_info.major,
+ sys.version_info.minor
+ )
+
+ ensurepip = os.path.normpath(
+ os.path.join(
+ os.path.dirname(bpy.app.binary_path_python),
+ "..", "lib", pyver, "ensurepip"
+ )
+ )
+ res = call(bpy.app.binary_path_python, ensurepip)
if res == 0:
import pip
else:
raise Exception("Failed to install pip.")
- print("Installing rhino3dm... "),
+ modulespath = os.path.normpath(
+ os.path.join(
+ bpy.utils.script_path_user(),
+ "addons",
+ "modules"
+ )
+ )
+ if not os.path.exists(modulespath):
+ os.makedirs(modulespath)
+ print("Installing rhino3dm to {}... ".format(modulespath)),
try:
from pip import main as pipmain
except:
from pip._internal import main as pipmain
- res = pipmain(["install", "rhino3dm"])
+ res = pipmain(["install", "--upgrade", "--target", modulespath, "rhino3dm"])
if res > 0:
raise Exception("Failed to install rhino3dm.")
except:
raise Exception("Failed to install dependencies. Please make sure you have pip installed.")
Does this work for you?
There, I managed to fix this and have pip
and rhino3dm
nicely install automatically on Windows.
We can use this as basis for getting something similar to work on Linux and MacOS.
@tsvilans thanks for your patch! And apologies it took so long to get it done.
Update materials option
Adds option to update previously imported materials.
detailed explanation
Automatically install dependencies
Tries to import
rhino3dm
and installs it usingpip
if it fails.detailed explanation
rhino3dm
, attempts to install it usingpip
pip
, installs it if it fails