TheComet / ik

Minimal Inverse Kinematics library
MIT License
488 stars 70 forks source link

How to use the Python bindings? #1

Open carlo- opened 5 years ago

carlo- commented 5 years ago

I'm interested in running the FABRIK solver from Python, but the bindings don't seem to work. I'm unable to initialize the solver (it seems that the call to the initializer is commented out) and other classes as well. Do you have any pointers on how to make it work?

TheComet commented 5 years ago

Hi carlo, thanks for reaching out!

Unfortunately, the python bindings are incomplete at this point. The Node and Solver objects are not exposed at all, so there's no way to use them in python.

This is partially due to the ownership model used by the node tree. Because child nodes are owned by parent nodes (destroying a node will destroy all children recursively) wrapping node objects for python is difficult. Python has to be notified whenever a node is deleted out from under it, as there is no way to forcefully delete a PyObject.

This, among other things, annoyed me, so I rewrote a lot of the node code to use a refcount based model instead (see devel branch) but that's not in a usable state at the moment.

So yeah. I can't give you a definite date as to when the python bindings become stable. My recommendation is if you need FABRIK in python and you can't wait months, it's not too hard to implement it yourself.

carlo- commented 5 years ago

I see! Thanks for the detailed answer.

TheComet commented 4 years ago

@carlo- I know it's been a while but the python API is slowly becoming usable. If you are still interested you can look at the sample I wrote. Setting it up is a bit jank at the moment but here's a step by step:

Install dependencies for building with python (I'm on ubuntu):

sudo apt install libpython3-dev

The demo uses pygame, which needs the following packages to build:

sudo apt install libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl1.2-dev libsmpeg-dev libportmidi-dev libswscale-dev libavformat-dev libavcodec-dev

Clone and checkout a version that works. I'm just giving you the commit hash for one that I know works.

git clone https://github.com/thecomet/ik
cd ik
git checkout e60e091d035e33a2ff491cdf8a0e77ec78a9d08f

Build as a python module:

mkdir build && cd build
cmake -DIK_PYTHON=ON ../
make

Set up a virtualenv in the samples folder:

cd ../samples/python-editor
virtualenv -p /usr/bin/python3 venv

Get the absolute path to ik.so which is under build/ik. On my machine that's /home/thecomet/programming/ik/build/ik. Add it to a .pth file:

echo /home/thecomet/programming/ik/build/ik > venv/lib/python3.8/site-packages/ik.pth

Activate the virtualenv and install pygame:

source venv/bin/activate
pip install pygame

Now you can run the demo:

python ik-editor.py
boughtonp commented 3 years ago

I tried following these instructions, but both e60e09 and devel were erroring on CMakeLists.txt:19 (The master branch appears to build ok, but doesn't produce an ik.so file.)

I eventually noticed the error was referring to a git submodule, so from main project dir I ran:

git submodule update --init thirdparty/cstructures/

Then returned to build dir and repeated the cmake and make commands, which completed and have produced an ik.so which I can import into python:

$ cd ik
$ python3
>>> import ik
>>> print(ik)
<module 'ik' from '/path/to/ik/build/ik/ik.so'>

This was on current HEAD of devel branch (c8f847)

Just completed the remaining virtualenv/pygame steps and the default ik-editor example works too.

(I tried uncommenting the human_example and it errors with "argument 1 must be ik.Bone, not ik.Node" - not sure if that's a problem with the library or example code, but since I need this for humans I'll poke around and see if I can figure it out.)

TheComet commented 3 years ago

Hey!

The human example works on 430fe60d128b4ba5503933a6a509cd97d0bd7c02 if you want to give that a go.

I'm sorry to have caused so much trouble, but sadly this library just isn't ready yet to be used properly. I am trying to satisfy many different needs and keep making pretty major changes.

boughtonp commented 3 years ago

Thanks.

This was far less effort compared to other IK projects I've been trying to use - simply having something that compiles is a big step forward.

LiorKirsch commented 3 years ago

I am also trying to build e60e09, but it fails to compile with the "-DIK_PYTHON=ON" flag. I think it is unable to find the docs. This it the error I get: /workspace/ik/ik/src/python/ik_type_Attachment.c:58:70: error: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] {"node", (getter)Attachment_getnode, (setter)Attachment_setnode, IK_ATTACHMENT_NODE_DOC, NULL}, Any thoughts?

TheComet commented 3 years ago

@LiorKirsch I'm trying to reproduce this error but am unable to.

I think you forgot to checkout e60e091 because IK_ATTACHMENT_NODE_DOC doesn't exist in that version yet.

Oh, when you check out a specific revision, also make sure to run git submodule update so the correct submodule versions are checked out as well. Maybe that will help fix some problems.

LiorKirsch commented 3 years ago

Thanks for the help. I have got a little further with the e60e091 commit and the submodule update But, I am still not able to compile it sucessefully.

Here is what I am doing: git clone https://github.com/TheComet/ik/ cd ik
git checkout e60e091
git submodule update --init thirdparty/cstructures git submodule update --init thirdparty/googletest/
git submodule update --init thirdparty/benchmark/
mkdir build
cd build cmake -DIK_PYTHON=ON ../
make

Here is the compilation error I get

/ik/ik/src/python/ik_type_Node.c:1174:9: error: implicit declaration of function ‘Py_RETURN_RICHCOMPARE’; did you mean ‘Py_RETURN_NONE’? [-Wimplicit-function-declaration] Py_RETURN_RICHCOMPARE(self->node->user.ptr, ikother->node->user.ptr, op); ^~~~~ Py_RETURN_NONE

TheComet commented 3 years ago

@LiorKirsch What python version are you on? I'm not sure when they introduced that macro but I think it's 3.7 or later.

You can probably just copy/paste the following into ik_type_Node.c:

/* Rich comparison opcodes */
#define Py_LT 0
#define Py_LE 1
#define Py_EQ 2
#define Py_NE 3
#define Py_GT 4
#define Py_GE 5

/*
 * Macro for implementing rich comparisons
 *
 * Needs to be a macro because any C-comparable type can be used.
 */
#define Py_RETURN_RICHCOMPARE(val1, val2, op)                               \
    do {                                                                    \
        switch (op) {                                                       \
        case Py_EQ: if ((val1) == (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
        case Py_NE: if ((val1) != (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
        case Py_LT: if ((val1) < (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;   \
        case Py_GT: if ((val1) > (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;   \
        case Py_LE: if ((val1) <= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
        case Py_GE: if ((val1) >= (val2)) Py_RETURN_TRUE; Py_RETURN_FALSE;  \
    } while (0)
LiorKirsch commented 3 years ago

I can confirm that upgrading to python3.8 solved these errors. Now I am able to build and run the samples.

Many thanks.

sulei1998 commented 3 years ago

emm, sorry to bother you, but when i checkout the branch, i met some problem. Like this:

error: pathspec 'e60e091' did not match any file(s) known to git.

image Could you help me?

TheComet commented 3 years ago

Hi @sulei1998

Sorry for the inconvenience. I did a history rewrite. The commit hash has changed to 35bcb3d2a60f8214c83264eba3542884438038e2

git clone https://github.com/thecomet/ik
cd ik
git checkout 35bcb3d2a60f8214c83264eba3542884438038e2
git submodule init
git submodule update
mkdir build && cd build
cmake -DIK_PYTHON=ON ../
make -j
sulei1998 commented 3 years ago

Hi @sulei1998

Sorry for the inconvenience. I did a history rewrite. The commit hash has changed to 35bcb3d

git clone https://github.com/thecomet/ik
cd ik
git checkout 35bcb3d2a60f8214c83264eba3542884438038e2
git submodule init
git submodule update
mkdir build && cd build
cmake -DIK_PYTHON=ON ../
make -j

Thanks for your quick reply! I followed your guide. My python version is 3.8.6. And i just followed what you say.

 git clone https://github.com/thecomet/ik
cd ik
git checkout 35bcb3d2a60f8214c83264eba3542884438038e2
git submodule init
git submodule update
mkdir build && cd build
cmake -DIK_PYTHON=ON ../
make -j
> 

But, I am still not able to compile it sucessefully. The error is:

/usr/bin/ld: /usr/local/lib/libpython3.8.a(_warnings.o): relocation R_X86_64_PC32 against symbol `_PyRuntime' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: The last link failed: wrong value
collect2: error: ld returned 1 exit status
ik/CMakeFiles/ik.dir/build.make:157: recipe for target 'ik/ik.so.0.2.0' failed
make[2]: *** [ik/ik.so.0.2.0] Error 1
CMakeFiles/Makefile2:250: recipe for target 'ik/CMakeFiles/ik.dir/all' failed
make[1]: *** [ik/CMakeFiles/ik.dir/all] Error 2
Makefile:148: recipe for target 'all' failed
make: *** [all] Error 2

Could you give me some advice?

TheComet commented 3 years ago

@sulei1998 Most likely you don't have the shared library of libpython installed. You can try:

cmake -DPython_USE_STATIC_LIBS=FALSE ../

to enforce finding the shared libs only. Make sure you have libpython3.x.so installed.

sulei1998 commented 3 years ago

@sulei1998 Most likely you don't have the shared library of libpython installed. You can try:

cmake -DPython_USE_STATIC_LIBS=FALSE ../

to enforce finding the shared libs only. Make sure you have libpython3.x.so installed.

Thanks for your kind help! Now i can run the ik-editor.py! Have a good day! :)