Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rhino scripts default install path is wrong for Rhino 8 #1351

Open
obucklin opened this issue May 2, 2024 · 15 comments
Open

Rhino scripts default install path is wrong for Rhino 8 #1351

obucklin opened this issue May 2, 2024 · 15 comments

Comments

@obucklin
Copy link

obucklin commented May 2, 2024

python -m compas_rhino.install adds the COMPAS packages to ~/.rhinocode/py27-rh8/Lib/site-packages instead of \AppData\Roaming\McNeel\Rhinoceros\8.0\scripts. Grasshopper components cannot then import the modules.

there is a workaround which is to include

pt = r"C:\Users\obucklin/.rhinocode/py27-rh8/Lib/site-packages"

if pt not in sys.path:
    sys.path.append(pt)

at the top of a python component. This fixes IronPython components.

I'm not sure if it's the same problem, but cpython components built with invoke build-cpython-ghuser-components do not instantiate on the canvas and result in a User Object failed to deserialize error:

image

Windows 11
Rhino 8 SR6 2024-4-10
COMPAS 2.1.0

Thanks!

@petrasvestartas
Copy link
Contributor

petrasvestartas commented May 2, 2024

I guess ScriptEditor usage for Rhino8 is still experimental as stated in the Compas documentation:
image

import compas_rhino.install

Python library installation directory and Grasshopper are two different directories.

What works for me is following:

Grasshopper for ScriptEditor Rhino8 CPython on Windows:
python src\rhino\gh\componentize_cpy.py src\rhino\gh\cpy %APPDATA%\Grasshopper\UserObjects

on mac
python src/rhino/gh/componentize_cpy.py src/rhino/gh/cpy "/Users/petras/Library/Application Support/McNeel/Rhinoceros/8.0/Plug-ins/Grasshopper (b45a29b1-4343-4035-989e-044e8580d9cf)/UserObjects"

or the package manager directory (manual upload to Rhino).

The python libraries I install as described in compas main page:
https://compas.dev/compas/latest/userguide/cad.rhino8.html
When a library is ready, I do it via pip, since this is the only possible solution to link a library in script editor is via # r: keyword.
Conda environments will be supported "maybe" in the future. This whole thing is painful, but at least it is CPython not IronPython...

@gonzalocasas gonzalocasas changed the title componentizer default install path is wrong for Rhino 8 Rhino scripts default install path is wrong for Rhino 8 May 2, 2024
@ChiaChing-Yen
Copy link

@petrasvestartas I followed this thread and it suggests adding # env: /path/to/site-package to the script to enable using that environment in Rhino. After adding this line, there's no need to use # r: module.
I used conda to create an environment with the same Python version as Rhino 8, then installed compas and compas_fab packages. I tried importing the modules, and they worked successfully.
While I haven't investigated this further, it seems like a viable workaround to make conda work with Rhino 8.

@gonzalocasas
Copy link
Member

This is very good news! Thanks @ChiaChing-Yen !

@jf---
Copy link
Contributor

jf--- commented Aug 6, 2024

I've run into the same issue: compas explicitly installs in the ironpython folder (/.rhinocode/py27-rh8/Lib/site-packages vs /.rhinocode/py39-rh8/Lib/site-packages, over rhino3, which seems at odds with the herculean effort of the compas team working towards python3 compatibility.

    # In Rhino 8 there is no scripts folder
    if version == "8.0":
        installation_path = compas_rhino._get_default_rhino_ironpython_sitepackages_path(version)
    else:
        installation_path = compas_rhino._get_rhino_scripts_path(version)

So @obucklin suggestion makes perfect sense to install into the scripts directory, so just factoring out the if statement should resolve things:

In [6]: compas_rhino._get_rhino_scripts_path("8.0")
Out[6]: '/Users/jelle/Library/Application Support/McNeel/Rhinoceros/8.0/scripts'

In my view, this is a pressing issue, given that compas is getting increasing less / incompatible with ironpython and the considerable hinderance associated to running iron python (no numpy etc). To speak for myself: python3 compatibility was more then sufficient reason to move to rhino 8 ;)

@tomvanmele
Copy link
Member

not sure i understand what is being proposed.

the current installation mechanism is not wrong. in Rhino 8, COMPAS packages should indeed be installed in the site packages folder of the Python flavour and version you intend to use. there are two reasons for this.

  1. if the scripts folder is used we can't differentiate between IronPython and CPython installs. using the scripts folder can create really weird clashes between packages and package versions that are difficult to debug.
  2. specifically for CPython installs, pip can now be used to install packages directly from the Python Package Index. if we install packages in the scripts folder using symlinks as we did with older versions of Rhino, this installation mechanism no longer works properly.

if there are other problems with correct versions of packages not being found by other components of Rhino, i would prefer trying to solve those problems specifically. changing the installation mechanism is not the solution in my opinion...

@chenkasirer
Copy link
Member

Sorry, I'm late for the party.
I made #1384 and only then saw this thread after..

@tomvanmele could you please elaborate on point 1.? I don't quite get it.

I find installing compas to 3 places is necessary in Rhino8 as there seems to be 3 different interpreters (or 2 in 3 environments):

  • Legacy IronPython (Old label)
  • IronPython (this is both new GH IronPython components and the EditPythonCode diaglog in Rhino)
  • CPython

And the corresponding locations are:

  • McNeel/Rhinoceros/8.0/scripts
  • py27-rh8/Lib/site-packages
  • py39-rh8/lib/site-packages

I do agree we should utilize the pip mechanism that's now made possible but I had some weird issue happening when I tried it out with compas_rhino.install_with_pip plus I think it should eventually be integrated into the compas_rhino.install.

Another related issue I'm having is I cannot for the life of me import compas_ghpython in a python3 components. It doesn't matter if I install via pip or with symlinks. Just getting this persistent NotSupportedInGHException. It seems to be for some call related to layers but even removing all those I could find didn't get me anywhere.

Any of you stumbled upon that or had better luck?

@tomvanmele
Copy link
Member

can we either close this issue or add an update about the current status?

based on some of the questions i have been receiving it is a source of confusion for people...

@gonzalocasas
Copy link
Member

We need to fix the GH components situation in order to really close this as solved. Right now, GH components of extensions (including those few ones in core), do not work on rhino 8.

@tomvanmele
Copy link
Member

tomvanmele commented Nov 15, 2024

not sure if they are helpful, but here are a few thoughts...

Rhino CPython (py39)

Basic users should use the default installation mechanism provided by Rhino, using # r: compas, ....

#! python3
# r: compas, ...

Different combinations of requirements for different projects can be isolated from each other using # venv: ....

#! python3
# venv: projectA
# r: compas, ...

More advanced users may want to/need to use pip directly themselves instead of using # r: .... There are two options:

  • use Rhino's pip
  • use the pip of a external (conda) environment with the correct --target.

the target directive can also be combined with the usage of Rhino's pip to install packages into specific venv. not however, that Rhino adds a random string to the names of the virtual environments in site-envs (don't know why) and that you need to know what this string is in order to use --target properly.

Rhino pip

Install compas into the default site-env using Rhino's pip, directly from PyPI:

~/.rhinocode/py39-rh8/python3.9 -m pip install compas

Install compas into a specific site-env ("projectA") using Rhino's pip, directly from PyPI:
(The random string i used ("projectA-htl4ZgZ0") will be different for everyone, and needs to be looked up first.)

~/.rhinocode/py39-rh8/python3.9 -m pip install compas --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0

The same can be done with source installs into the default or a specific site-env:

cd path/to/compas
~/.rhinocode/py39-rh8/python3.9 -m pip install .
cd path/to/compas
~/.rhinocode/py39-rh8/python3.9 -m pip install . --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0

NOT Rhino pip

Instead of using Rhino's pip, you can also use the pip of an external environment you might be working in (ideally this environment is based on Python 3.9, but depending on the requirements of the packages you install this is not always absolutely necessary). however, in this case --target is not optional, even for the default site-env.

conda activate compas-dev
cd path/to/compas
python -m pip install . --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0

Using an external environment directly as suggested above (using # env: path/to/site-packages) is not something i have been able to get to work, but i have only tried it on Mac. In any case, i doubt it will work for packages that are built and have build requirements like compas_cgal.

Rhino IronPython

the "py27-rh8" folder has a very similar structure as the one of "py39-rh8" so i assume that at least the installation procedures listed above that use local source will work as well, but i haven't tried this...

GH

About Grasshopper i have no idea, but i can confirm that Python 3 components have access to the same "site-envs" as the Rhino ScriptEditor.

Screenshot 2024-11-15 at 14 24 55

@chenkasirer
Copy link
Member

chenkasirer commented Nov 15, 2024

That is my understanding of the situation as well.

We're basically retiring the compas_rhino.install mechanism, where, starting from Rhino8, you're expected to install compas inside Rhino as you described above.
I find the instructions in https://compas.dev/compas/latest/userguide/cad.rhino8.html pretty clear and complete.

Perhaps we should remove the Rhino8 switch from compas_rhino.install so that it's not used as well as provide some kind of an uninstall script to allow removing COMPAS symlinks from AppData\Roaming\McNeel\Rhinoceros\8.0\scripts in case anyone has them there. This as a replacement for this PR #1383 if @tetov agree.

Once we've dealt with that, I'm fine with closing this issue.

Regarding Grasshopper

I think the way forward is components with #r: .. in header and that are distributed as YAK packages over Food4Rhino.
We'd probably need to separate the IPY and CPython component definitions and make some changes to compas_invocation2 as well as integrate that to the componentizer action.

We're currently trying this out with COMPAS Timber. still some things that used to work differently in Rhino7 we're struggling with. will update.

For completeness sake I'll just mention that this #r: ... syntax doesn't quite work for me in the IronPython components in Rhino8. maybe I'll post in the mcneel forum.

Finally there's the legacy ironpython components which perhaps we shouldn't support.

Maybe we can post updates about the Grasshopper situation somewhere, pinned discussion in the forum? a new issue?

@chenkasirer
Copy link
Member

chenkasirer commented Nov 15, 2024

One open question for me is how to continue supporting Rhino7 Grasshopper component installation. If we continue installing the user objects to the same place we do now (AppData\Roaming\Grasshopper\UserObjects) the components appear in both Rhino7 and Rhino8..

Evidently, you can get Grasshopper plugins for Rhino7 over Food4Rhino they are then presumably installed to \AppData\Roaming\McNeel\Rhinoceros\packages\7.0 , but how they manage python library dependencies I have no idea.

@tomvanmele
Copy link
Member

tomvanmele commented Nov 16, 2024

it sounds like AppData\Roaming\Grasshopper\UserObjects is more or less the equivalent of the scripts folder. can we not install directly into AppData\Roaming\McNeel\Rhinoceros\packages\7.0?

that way 7.0 and 8.0 are cleanly separated, which allows us to use different installation and dependency management approaches in both cases...

@chenkasirer
Copy link
Member

chenkasirer commented Nov 19, 2024

Agree.
to sum up and make actionable I propose the following (I can make the changes)

  • compas_invocations2 add ability to distinguish between component source for ironpython and cpython (as these will most likely need to co-exist)
  • compas-actions.ghpython_components add the yakerize.py script (thanks @9and3!) to the componentizer and expose it via the github action
  • compas_invocations2 add yakerize invoke command to allow local packaging
  • compas - remove the 8.0 flag from compas_rhino.install
  • compas - add cpython compatible copy of the components to compas_ghpython\components_cpython
  • compas-actions.build/publish - extend to build yak packages for rhino7 and rhino8

when using YAK, components are installed to AppData\Roaming\McNeel\Rhinoceros\packages\7.0 and ...\8.0
the Rhino8 components need to have #r: compas at the top which will take care of the python dependencies.

Rhino7 components would need the good old compas_rhino.install -v7.0 to have their dependencies available (AKA symlinks in \AppData\Roaming\McNeel\Rhinoceros\7.0\scripts)

@tomvanmele
Copy link
Member

@tetov ping

@tomvanmele
Copy link
Member

@chenkasirer just fyi...

when releasing the new version of RhinoVault through Yak, we noticed that, at least on the Rhino side, you have to be careful with the requirements inside the command scripts. for some strange reason, even if there are no conflicts between versions, having compas listed alongside other requirements which in turn listed compas as one of their requirements in their requirements.txt made the commands reinstall all requirements every time they were run. once we removed compas from the list, the problem went away...

the problem didn't occur as long as we were using locally build packages.

for example, a script with # r: compas, compas_tna, compas_session would trigger this behaviour.

however, the same script with # r: compas_tna, compas_session would not...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants