FreeCAD api fails in external application

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
drmacro
Veteran
Posts: 8870
Joined: Sun Mar 02, 2014 4:35 pm

Re: FreeCAD api fails in external application

Post by drmacro »

wmayer wrote: Sat Apr 30, 2022 3:52 pm ...
Where is the PartDesign directory located? You can figure this out by importing PartDesignGui (which I think should work). Then check the path name of its __file__ attribute. Open this directory in a file manager and look for the __init__.py file. If it doesn't exist create it and set its content to:

Code: Select all

import _PartDesign
makeFilletArc = _PartDesign.makeFilletArc
Now try to load the project file with Blender again.
Since this didn't work, I've been poking around trying to figure out if there is any other by hand fix I might be able to use.

I'm, by far, not a Python-ista...

As I understand the __init__.py system, if I use the line "import <module name>" and that name is a directory and that directory contains a file named __init__.py, then it executes whatever Python is in the __init__.py file.

So, I think for the line "import PartDesign" to work at the Python console in Blender, there must be a directory, somewhere, named (or symbolic link?) called PartDesign.

If this is correct, there is no such thing on either of the Manjaro/AUR installations I have...

How is this supposed to work? If I get to understand that, maybe a can get further.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
drmacro
Veteran
Posts: 8870
Joined: Sun Mar 02, 2014 4:35 pm

Re: FreeCAD api fails in external application

Post by drmacro »

@wmayer
@adrianinsaval
@kunda

More research and experimentation.

Basically the AUR install leave Python with no way to find PartDesign/__init__.py because it is just not resident in any of the directories where Python searches.

PartDesign/__init__.py does exist in /usr/lib/freecad/Mod

So, the following script allows Blender/sverchok to work with FreeCAD PartDesign objects:

Code: Select all

PYTHONPATH=/usr/lib/freecad/Mod
export PYTHONPATH
blender
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
User avatar
adrianinsaval
Veteran
Posts: 5541
Joined: Thu Apr 05, 2018 5:15 pm

Re: FreeCAD api fails in external application

Post by adrianinsaval »

so where should it be and were is it in reality? AUR version enables a build flag about using python site-packages directory, could that be related? it also makes some symlinks for the .so files
also could the problem be that sverchok was coded taking into account only the debian package file structure? I'm not sure if that is representative of FreeCAD's default installation paths
drmacro
Veteran
Posts: 8870
Joined: Sun Mar 02, 2014 4:35 pm

Re: FreeCAD api fails in external application

Post by drmacro »

adrianinsaval wrote: Tue May 10, 2022 6:34 pm so where should it be and were is it in reality? AUR version enables a build flag about using python site-packages directory, could that be related? it also makes some symlinks for the .so files
also could the problem be that sverchok was coded taking into account only the debian package file structure? I'm not sure if that is representative of FreeCAD's default installation paths
As I understand it, the Python import works like so:
  • import MyModule
  • python looks through the directories specified in a list (that list includes PYTHONPATH, if it exists)
  • MyModule.py is found somewhere in the list
  • MyModule.py is loaded
Or:
  • import MyModule
  • python looks through the directories specified in a list (that list includes PYTHONPATH, if it exists)
  • MyModule directory is found somewhere in the list
  • if __init__.py is found in MyModule, then __init__.py is executed.
The later is, as I understand, is how PartDesign is structured.

Currently, the AUR package, does not put PartDesign directory in site-packages, but does put _PartDesign and it contains __init__.py

PartDesign/__init__.py exists elsewhere, but "elsewhere" is not in the list that python has, so "import PartDesign" fails (this happend in the python interpreter as well as the Blender python terminal. I assume any app that attempted to use FreeCAD with python would fail as well. This leads me to think it is not a sverchok issue, since it fails in python.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
User avatar
adrianinsaval
Veteran
Posts: 5541
Joined: Thu Apr 05, 2018 5:15 pm

Re: FreeCAD api fails in external application

Post by adrianinsaval »

@wmayer could this be an error in the cmake files or just packaging error? here the commands used to build and install freecad from the AUR:

Code: Select all

_destdir="/usr"
  cmake -Wno-dev -G Ninja -B build_dir -S . \
    -D BUILD_ENABLE_CXX_STD=C++17 \
    -D BUILD_FEM=ON \
    -D BUILD_FEM_NETGEN=OFF \
    -D BUILD_MESH=ON \
    -D BUILD_FLAT_MESH=ON \
    -D BUILD_MESH_PART=ON \
    -D BUILD_SHIP=ON \
    -D BUILD_ASSEMBLY=ON \
    -D BUILD_COMPLETE=ON \
    -D BUILD_JTREADER=OFF \
    -D BUILD_PLOT=ON \
    -D BUILD_CLOUD=OFF \
    -D CMAKE_BUILD_TYPE=None \
    -D CMAKE_C_FLAGS="${CFLAGS} -fPIC -w" \
    -D CMAKE_CXX_FLAGS="${CXXFLAGS} -fPIC -w" \
    -D FREECAD_USE_EXTERNAL_PIVY=ON \
    -D FREECAD_USE_OCC_VARIANT="Official Version" \
    -D FREECAD_USE_QT_FILEDIALOG=ON \
    -D PYTHON_EXECUTABLE=/usr/bin/python \
    -D INSTALL_TO_SITEPACKAGES=ON \
    -D CMAKE_INSTALL_PREFIX="${_destdir}/lib/freecad" \
    -D CMAKE_INSTALL_BINDIR=bin \
    -D CMAKE_INSTALL_LIBDIR='../../lib' \
    -D CMAKE_INSTALL_DATADIR='../../share/freecad' \
    -D CMAKE_INSTALL_DATAROOTDIR='../../share' \
    -D CMAKE_INSTALL_DOCDIR='../../share/doc/freecad'
    
  cmake --build build_dir
  
  DESTDIR="${pkgdir}" cmake --install build_dir

  # link all the .sos into python site package dir
  python_site_packages="$(python -c 'import sys; print(sys.path[-1])')"
  mkdir -p "${pkgdir}/${python_site_packages}"
  FILES="${pkgdir}${_destdir}"/lib/*.so
  for f in $FILES
  do
    ln -s ${_destdir}/lib/$(basename $f) "${pkgdir}/${python_site_packages}/$(basename $f)"
  done

  # links for bin
  mkdir -p "${pkgdir}${_destdir}"/bin
  FILES="${pkgdir}${_destdir}"/lib/freecad/bin/*
  for f in $FILES
  do
    ln -s '../lib/freecad/bin/'$(basename $f) "${pkgdir}${_destdir}"/bin/$(basename $f)
  done

  # env var for __init__.py
  mkdir -p "${pkgdir}"/etc/profile.d
  echo "export PATH_TO_FREECAD_LIBDIR=${_destdir}/lib" > "${pkgdir}"/etc/profile.d/freecad.sh

  install -Dt "${pkgdir}${_destdir}/share/licenses/${pkgname}" -m644 LICENSE
User avatar
adrianinsaval
Veteran
Posts: 5541
Joined: Thu Apr 05, 2018 5:15 pm

Re: FreeCAD api fails in external application

Post by adrianinsaval »

the sverchok wiki mentioned configuring the path for FreeCAD libs, what path did you configure in the sverchok preferences @drmacro ?
drmacro
Veteran
Posts: 8870
Joined: Sun Mar 02, 2014 4:35 pm

Re: FreeCAD api fails in external application

Post by drmacro »

adrianinsaval wrote: Tue May 10, 2022 7:36 pm the sverchok wiki mentioned configuring the path for FreeCAD libs, what path did you configure in the sverchok preferences @drmacro ?
You can point it to the directory where PartDesign/__init__.py exits. It is not found because that doesn't add it to where python looks for it.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
User avatar
adrianinsaval
Veteran
Posts: 5541
Joined: Thu Apr 05, 2018 5:15 pm

Re: FreeCAD api fails in external application

Post by adrianinsaval »

drmacro wrote: Mon May 02, 2022 12:21 pm I have poked around in the directories until I've confused myself.

Is there some place I can look for what would be normal (and correct) as to where things should be after the AUR install has completed?

I'm wondering, if, on this Manjaro PC because I"ve done both a AUR build by hand and through pacman (and during the perios when the AUR build was completely bolloxed because of the jump to Python 3.10) that I have some sort of polluted install situation.
In case you are still interested in checking this

Code: Select all

pacman -Ql freecad-git 
should output a list of all the files installed by that package, if you suspect just your build is broken you can compare with the daily built package from chaotic-aur repo http://mirrors.fossho.st/garuda/repos/c ... ur/x86_64/
but if something is not were it should be it's probably for all AUR builds not just yours
drmacro
Veteran
Posts: 8870
Joined: Sun Mar 02, 2014 4:35 pm

Re: FreeCAD api fails in external application

Post by drmacro »

adrianinsaval wrote: Tue May 10, 2022 9:33 pm
drmacro wrote: Mon May 02, 2022 12:21 pm ...
In case you are still interested in checking this

Code: Select all

pacman -Ql freecad-git 
should output a list of all the files installed by that package, if you suspect just your build is broken you can compare with the daily built package from chaotic-aur repo http://mirrors.fossho.st/garuda/repos/c ... ur/x86_64/
but if something is not were it should be it's probably for all AUR builds not just yours
Thanks that a good one to know. I'll give it a go tomorrow.

But, I have two different machines with Manjaro, both exhibit the same conditions and work with the export PYTHONPATH. I'm guessing it's probably AUR.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: FreeCAD api fails in external application

Post by wmayer »

import PartDesignGui results in "Cannot load Gui module in console application"
OK, you can make it working by first doing:

Code: Select all

import FreeCADGui
FreeCADGui.setupWithoutGUI()
./usr/lib/python3.10/site-packages/PartDesignGui.so
./usr/lib/PartDesignGui.so
Are these identical files or do they come from different FreeCAD and/or Python versions?
In fact there is no PartDesign.so in any of those places, only _PartDesign.so:
Of course not. Only _PartDesign.so exists because this is the extension module that must have a different name than the PartDesign package. The latter is the directory with an __init__.py file inside
I think, I see after comparing to my Debian PC that there isn't supposed to be a PartDesign.so. Is this correct?
Yes.
In any case, simply adding the __init__.py didn't fix anything and as I noted, there is one already in another directory.
Only adding the file is not enough. You also must add the content to import _PartDesign

Code: Select all

import _PartDesign
makeFilletArc = _PartDesign.makeFilletArc
Is there some place I can look for what would be normal (and correct) as to where things should be after the AUR install has completed?
I don't know where AUR puts the stuff. Important is that the path to PartDesign is listed in sys.path, the directory contains an __init__.py file and that this file contains the above posted code.
As I understand the __init__.py system, if I use the line "import <module name>" and that name is a directory and that directory contains a file named __init__.py, then it executes whatever Python is in the __init__.py file.
Yes. But the more important thing is that this file makes the containing directory a package.
So, I think for the line "import PartDesign" to work at the Python console in Blender, there must be a directory, somewhere, named (or symbolic link?) called PartDesign.
On the one system where it works you can check the __file__ attribute of the imported PartDesign that should give you an absolute path. The parent directory is the PartDesign directory.
could this be an error in the cmake files or just packaging error? here the commands used to build and install freecad from the AUR:
Looks OK to me. It creates /usr/lib/freecad and puts the bin and (I hope) the Mod directory inside there and the shared libraries go to /usr/lib
Post Reply