├── .gitignore ├── README.md ├── blender_ipython.py └── blender_ipython_wrapper.py /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | *~ 3 | __pycache__ 4 | *.pyc 5 | *.pyo 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | IPython for Blender 2 | =================== 3 | 4 | These scripts contain hacks in order to run [IPython][1] in the context of [Blender's][2] 5 | embedded Python interpreter. 6 | 7 | [1]: http://ipython.org/ 8 | [2]: http://www.blender.org/ 9 | 10 | Usage 11 | ----- 12 | 13 | Start an IPython Notebook: 14 | 15 | ./blender_ipython.py notebook 16 | 17 | 18 | Start a Qt Console: 19 | 20 | ./blender_ipython.py qtconsole 21 | 22 | Installing Jupyter/Ipython Kernel 23 | ------------ 24 | 25 | - [Find the jupyter kernel path for your system](http://jupyter-client.readthedocs.org/en/latest/kernels.html) and create a blender directory. On unix this is `~/.local/share/jupyter/kernels` 26 | 27 | - Place a kernel.json file in the directory `~/.local/share/jupyter/kernels/blender/kernel.json` 28 | - The contents of the json are as follows, where you replace "PATH_TO_SCRIPT" with the actual path 29 | ```json 30 | { 31 | "argv": ["PATH_TO_SCRIPT/blender_ipython.py", "kernel", 32 | "-f", "{connection_file}"], 33 | "display_name": "Blender env", 34 | "language": "python" 35 | } 36 | ``` 37 | - now start the notebook normally (`jupyter notebook`) and you will see a new kernel under "new" called blender. 38 | - make a new notebook using this kernel and test it by running `import bpy` 39 | - you are now set up 40 | 41 | Dependencies 42 | ------------ 43 | 44 | * [Python][3] 3.3 (not tested with Python 3.4) 45 | * [IPython][1] 0.13 for Python 3 (not tested with IPython 1.x) 46 | * [Blender][2] 47 | 48 | I only have Python 3.3 and IPython 0.13 and thus this was not tested with any newer versions. Because this scripts use big hacks to get the IPython kernel running in Blender it is very likely that it won't work with any other versions. In fact I got bug reports where people with Python 3.4 and IPython 1.x could not get it to work. 49 | 50 | [3]: https://www.python.org/ 51 | 52 | The MIT License (MIT) 53 | --------------------- 54 | 55 | Copyright (c) 2014 Mathias Panzenböck 56 | 57 | Permission is hereby granted, free of charge, to any person obtaining a copy 58 | of this software and associated documentation files (the "Software"), to deal 59 | in the Software without restriction, including without limitation the rights 60 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 61 | copies of the Software, and to permit persons to whom the Software is 62 | furnished to do so, subject to the following conditions: 63 | 64 | The above copyright notice and this permission notice shall be included in 65 | all copies or substantial portions of the Software. 66 | 67 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 68 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 69 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 70 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 71 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 72 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 73 | THE SOFTWARE. 74 | -------------------------------------------------------------------------------- /blender_ipython.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | if sys.argv[1:2] == ['kernel']: 6 | from blender_ipython_wrapper import launch_kernel 7 | launch_kernel(sys.argv[1:]) 8 | else: 9 | from os.path import abspath, dirname, join as pathjoin 10 | 11 | try: 12 | from IPython.frontend.terminal.ipapp import launch_new_instance 13 | except ImportError: 14 | from IPython.terminal.ipapp import launch_new_instance 15 | 16 | # use wrapper script for starting python processes 17 | # the wrapper will defer execution to blender, if it was used to start a new kernel 18 | sys.executable = pathjoin(dirname(abspath(sys.argv[0])), 'blender_ipython_wrapper.py') 19 | 20 | launch_new_instance() 21 | -------------------------------------------------------------------------------- /blender_ipython_wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | import tempfile 7 | 8 | __all__ = 'launch_kernel', 'main' 9 | 10 | def launch_kernel(argv): 11 | tempscript = tempfile.mktemp()+"_blender_ipython_kernel.py" 12 | 13 | # generate kernel starter script 14 | with open(tempscript,"w") as f: 15 | f.write("""\ 16 | import sys 17 | sys.argv[:] = [sys.executable] 18 | try: 19 | from IPython.zmq.ipkernel import IPKernelApp 20 | except ImportError as err: 21 | from ipykernel.kernelapp import IPKernelApp 22 | 23 | app = IPKernelApp.instance() 24 | app.initialize(%r) 25 | app.start() 26 | """ % argv) 27 | 28 | try: 29 | print('starting: blender -b -P', tempscript) 30 | sys.exit(subprocess.call(['blender', '-b', '-P', tempscript])) 31 | finally: 32 | os.remove(tempscript) 33 | 34 | def main(): 35 | if sys.argv[1:3] != ['-c', 'from IPython.zmq.ipkernel import main; main()']: 36 | # if it wasn't used to start a kernel really execute python 37 | os.execlp('python3','python3',*sys.argv[1:]) 38 | else: 39 | launch_kernel(sys.argv[1:]) 40 | 41 | if __name__ == '__main__': 42 | main() 43 | --------------------------------------------------------------------------------