diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-06-18 00:52:52 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-06-18 01:00:46 +0300 |
commit | 18f228d593123cf7fd6eef7ceda27a1c092e1df8 (patch) | |
tree | fcdc95f8bdcf5f120af9ce8ba355d7303eccb3ed /doc/python_api/rst | |
parent | a62392dea7e6c99ad00dda8a2080d3944e9536cf (diff) |
update hand written rst docs
- minor corrections
- link to new manual
- wrap lines at 120
Diffstat (limited to 'doc/python_api/rst')
-rw-r--r-- | doc/python_api/rst/info_api_reference.rst | 44 | ||||
-rw-r--r-- | doc/python_api/rst/info_best_practice.rst | 175 | ||||
-rw-r--r-- | doc/python_api/rst/info_overview.rst | 192 | ||||
-rw-r--r-- | doc/python_api/rst/info_quickstart.rst | 103 | ||||
-rw-r--r-- | doc/python_api/rst/info_tips_and_tricks.rst | 164 | ||||
-rw-r--r-- | doc/python_api/rst/info_tutorial_addon.rst | 10 |
6 files changed, 429 insertions, 259 deletions
diff --git a/doc/python_api/rst/info_api_reference.rst b/doc/python_api/rst/info_api_reference.rst index ddee46dce11..43469fc0cb7 100644 --- a/doc/python_api/rst/info_api_reference.rst +++ b/doc/python_api/rst/info_api_reference.rst @@ -121,7 +121,7 @@ Here are some more complex examples: bpy.context.scene.render.layers["RenderLayer"].samples # access to the current weight paint brush size - bpy.context.tool_settings.weight_paint.brush.size + bpy.context.tool_settings.weight_paint.brush.size # check if the window is fullscreen bpy.context.window.screen.show_fullscreen @@ -141,15 +141,16 @@ When starting out scripting you will often run into the problem where you're not There are a few ways to do this. -- Use the Python console's auto-complete to inspect properties. *This can be hit-and-miss but has the advantage +- Use the Python console's auto-complete to inspect properties. + *This can be hit-and-miss but has the advantage that you can easily see the values of properties and assign them to interactively see the results.* +- Copy the Data-Path from the user interface. + *Explained further in :ref:`Copy Data Path <info_data_path_copy>`* +- Using the documentation to follow references. + *Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`* -- Copy the Data-Path from the user interface. *Explained further in :ref:`Copy Data Path <info_data_path_copy>`* -- Using the documentation to follow references. *Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`* - - -.. _info_data_path_copy +.. _info_data_path_copy: Copy Data Path -------------- @@ -172,7 +173,8 @@ you won't be doing collection look-ups on every access and typically you'll want then access each :class:`bpy.types.ID` instance by name. -Type in the ID path into a Python console :mod:`bpy.context.active_object`. Include the trailing dot and don't hit "enter", yet. +Type in the ID path into a Python console :mod:`bpy.context.active_object`. +Include the trailing dot and don't hit "enter", yet. Now right-click on the button and select **Copy Data Path**, then paste the result into the console. @@ -191,7 +193,7 @@ Hit "enter" and you'll get the current value of 1. Now try changing the value to You can see the value update in the Subdivision-Surface modifier's UI as well as the cube. -.. _info_data_path_indirect +.. _info_data_path_indirect: Indirect Data Access -------------------- @@ -201,32 +203,24 @@ For this example we'll go over something more involved, showing the steps to acc Lets say we want to access the texture of a brush via Python, to adjust its ``contrast`` for example. - Start in the default scene and enable 'Sculpt' mode from the 3D-View header. - - From the toolbar expand the **Texture** panel and add a new texture. - *Notice the texture button its self doesn't have very useful links (you can check the tool-tips).* - - The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel... - In the properties button select the Texture context. - - Select the Brush icon to show the brush texture. - - - Expand the **Colors** panel to locate the **Contrast** button. - -- Right click on the contrast button and select **Online Python Reference** This takes you to ``bpy.types.Texture.contrast`` - -- Now we can see that ``contrast`` is a property of texture, so next we'll check on how to access the texture from the brush. - + - Expand the *Colors* panel to locate the *Contrast* button. +- Right click on the contrast button and select **Online Python Reference** + This takes you to ``bpy.types.Texture.contrast`` +- Now we can see that ``contrast`` is a property of texture, + so next we'll check on how to access the texture from the brush. - Check on the **References** at the bottom of the page, sometimes there are many references, and it may take some guess work to find the right one, but in this case its obviously ``Brush.texture``. *Now we know that the texture can be accessed from* ``bpy.data.brushes["BrushName"].texture`` *but normally you won't want to access the brush by name, so we'll see now to access the active brush instead.* - - So the next step is to check on where brushes are accessed from via the **References**. In this case there is simply ``bpy.context.brush`` which is all we need. - Now you can use the Python console to form the nested properties needed to access brush textures contrast, logically we now know. @@ -282,7 +276,8 @@ are interested to check on the source code. .. note:: - Not all operators can be called usefully from Python, for more on this see :ref:`using operators <using_operators>`. + Not all operators can be called usefully from Python, + for more on this see :ref:`using operators <using_operators>`. Info View @@ -294,7 +289,8 @@ This is located above the file-menu which can be dragged down to display its con Select the **Script** screen that comes default with Blender to see its output. You can perform some actions and see them show up - delete a vertex for example. -Each entry can be selected (Right-Mouse-Button), then copied :kbd:`Control-C`, usually to paste in the text editor or python console. +Each entry can be selected (Right-Mouse-Button), +then copied :kbd:`Control-C`, usually to paste in the text editor or python console. .. note:: diff --git a/doc/python_api/rst/info_best_practice.rst b/doc/python_api/rst/info_best_practice.rst index 1e12daba893..8c5ae3398bc 100644 --- a/doc/python_api/rst/info_best_practice.rst +++ b/doc/python_api/rst/info_best_practice.rst @@ -1,16 +1,20 @@ + ************* Best Practice ************* -When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand. +When writing your own scripts python is great for new developers to pick up and become productive, +but you can also pick up odd habits or at least write scripts that are not easy for others to understand. -For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage. +For your own work this is of course fine, +but if you want to collaborate with others or have your work included with blender there are practices we encourage. Style Conventions ================= -For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles amongst our own scripts and make it easier to use python scripts from other projects. +For Blender/Python development we have chosen to follow python suggested style guide to avoid mixing styles +amongst our own scripts and make it easier to use python scripts from other projects. Using our style guide for your own scripts makes it easier if you eventually want to contribute them to blender. @@ -18,22 +22,17 @@ This style guide is known as pep8 and can be found `here <http://www.python.org/ A brief listing of pep8 criteria. -* camel caps for class names: MyClass - -* all lower case underscore separated module names: my_module - -* indentation of 4 spaces (no tabs) - -* spaces around operators. ``1 + 1``, not ``1+1`` - -* only use explicit imports, (no importing '*') - -* don't use single line: ``if val: body``, separate onto 2 lines instead. +- camel caps for class names: MyClass +- all lower case underscore separated module names: my_module +- indentation of 4 spaces (no tabs) +- spaces around operators. ``1 + 1``, not ``1+1`` +- only use explicit imports, (no importing ``*``) +- don't use single line: ``if val: body``, separate onto 2 lines instead. As well as pep8 we have other conventions used for blender python scripts. -* Use single quotes for enums, and double quotes for strings. +- Use single quotes for enums, and double quotes for strings. Both are of course strings but in our internal API enums are unique items from a limited set. eg. @@ -42,9 +41,11 @@ As well as pep8 we have other conventions used for blender python scripts. bpy.context.scene.render.image_settings.file_format = 'PNG' bpy.context.scene.render.filepath = "//render_out" -* pep8 also defines that lines should not exceed 79 characters, we felt this is too restrictive so this is optional per script. +- pep8 also defines that lines should not exceed 79 characters, + we felt this is too restrictive so this is optional per script. -Periodically we run checks for pep8 compliance on blender scripts, for scripts to be included in this check add this line as a comment at the top of the script. +Periodically we run checks for pep8 compliance on blender scripts, +for scripts to be included in this check add this line as a comment at the top of the script. ``# <pep8 compliant>`` @@ -58,72 +59,75 @@ User Interface Layout Some notes to keep in mind when writing UI layouts: -* UI code is quite simple. Layout declarations are there to easily create a decent layout. +- UI code is quite simple. Layout declarations are there to easily create a decent layout. + + General rule here: If you need more code for the layout declaration, + then for the actual properties, you do it wrong. - General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong. - Example layouts: -* layout() +- layout() + + The basic layout is a simple Top -> Bottom layout. - The basic layout is a simple Top -> Bottom layout. - .. code-block:: python - layout.prop() - layout.prop() + layout.prop() + layout.prop() + +- layout.row() -* layout.row() + Use row(), when you want more than 1 property in one line. - Use row(), when you want more than 1 property in one line. - .. code-block:: python - - row = layout.row() - row.prop() - row.prop() -* layout.column() + row = layout.row() + row.prop() + row.prop() + +- layout.column() Use column(), when you want your properties in a column. - + .. code-block:: python - - col = layout.column() - col.prop() - col.prop() -* layout.split() + col = layout.column() + col.prop() + col.prop() - This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other. +- layout.split() + + This can be used to create more complex layouts. + For example you can split the layout and create two column() layouts next to each other. Don't use split, when you simply want two properties in a row. Use row() for that. - + .. code-block:: python - - split = layout.split() - - col = split.column() - col.prop() - col.prop() - - col = split.column() - col.prop() - col.prop() - + + split = layout.split() + + col = split.column() + col.prop() + col.prop() + + col = split.column() + col.prop() + col.prop() + Declaration names: Try to only use these variable names for layout declarations: -* row for a row() layout -* col for a column() layout -* split for a split() layout -* flow for a column_flow() layout -* sub for a sub layout (a column inside a column for example) +- row for a row() layout +- col for a column() layout +- split for a split() layout +- flow for a column_flow() layout +- sub for a sub layout (a column inside a column for example) Script Efficiency ================= + List Manipulation (General Python Tips) --------------------------------------- @@ -133,7 +137,8 @@ Searching for list items In Python there are some handy list functions that save you having to search through the list. -Even though you're not looping on the list data **python is**, so you need to be aware of functions that will slow down your script by searching the whole list. +Even though you're not looping on the list data **python is**, +so you need to be aware of functions that will slow down your script by searching the whole list. .. code-block:: python @@ -145,11 +150,16 @@ Even though you're not looping on the list data **python is**, so you need to be Modifying Lists ^^^^^^^^^^^^^^^ -In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place. +In python we can add and remove from a list, this is slower when the list length is modified, +especially at the start of the list, since all the data after the index of +modification needs to be moved up or down 1 place. -The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``. +The most simple way to add onto the end of the list is to use +``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to +remove an item is ``my_list.pop()`` or ``del my_list[-1]``. -To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)`` for list removal, but these are slower. +To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(index)`` +for list removal, but these are slower. Sometimes its faster (but more memory hungry) to just rebuild the list. @@ -193,7 +203,8 @@ Use... my_list.extend([a, b, c...]) -Note that insert can be used when needed, but it is slower than append especially when inserting at the start of a long list. +Note that insert can be used when needed, +but it is slower than append especially when inserting at the start of a long list. This example shows a very sub-optimal way of making a reversed list. @@ -205,7 +216,8 @@ This example shows a very sub-optimal way of making a reversed list. reverse_list.insert(0, list_item) -Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much: +Python provides more convenient ways to reverse a list using the slice method, +but you may want to time this before relying on it too much: .. code-block:: python @@ -220,7 +232,8 @@ Use ``my_list.pop(index)`` rather than ``my_list.remove(list_item)`` This requires you to have the index of the list item but is faster since ``remove()`` will search the list. -Here is an example of how to remove items in 1 loop, removing the last items first, which is faster (as explained above). +Here is an example of how to remove items in 1 loop, +removing the last items first, which is faster (as explained above). .. code-block:: python @@ -232,7 +245,9 @@ Here is an example of how to remove items in 1 loop, removing the last items fir my_list.pop(list_index) -This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last. +This example shows a fast way of removing items, +for use in cases where you can alter the list order without breaking the scripts functionality. +This works by swapping 2 list items, so the item you remove is always last. .. code-block:: python @@ -251,7 +266,9 @@ When removing many items in a large list this can provide a good speedup. Avoid Copying Lists ^^^^^^^^^^^^^^^^^^^ -When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn't have to duplicate the list in memory. +When passing a list/dictionary to a function, +it is faster to have the function modify the list rather than returning +a new list so python doesn't have to duplicate the list in memory. Functions that modify a list in-place are more efficient than functions that create new lists. @@ -296,20 +313,26 @@ Python’s string joining function. To join a list of strings >>> file.write(" ".join([str1, str2, str3, "\n"])) -join is fastest on many strings, `string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`_ is quite fast too (better for converting data types). String arithmetic is slowest. +join is fastest on many strings, +`string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`__ +is quite fast too (better for converting data types). String arithmetic is slowest. Parsing Strings (Import/Exporting) ---------------------------------- -Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs. +Since many file formats are ASCII, +the way you parse/export strings can make a large difference in how fast your script runs. There are a few ways to parse strings when importing them into Blender. + Parsing Numbers ^^^^^^^^^^^^^^^ -Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but it's faster to read ints with int(). +Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, +float() will work for an int too but it's faster to read ints with int(). + Checking String Start/End ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -322,7 +345,8 @@ Use... >>> if line.startswith("vert "): -Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible error with the slice length not matching the string length. +Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible +error with the slice length not matching the string length. my_string.endswith("foo_bar") can be used for line endings too. @@ -336,15 +360,19 @@ Use try/except Sparingly The **try** statement is useful to save time writing error checking code. -However **try** is significantly slower than an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times. +However **try** is significantly slower than an **if** since an exception has to be set each time, +so avoid using **try** in areas of your code that execute in a loop and runs many times. -There are cases where using **try** is faster than checking whether the condition will raise an error, so it is worth experimenting. +There are cases where using **try** is faster than checking whether the condition will raise an error, +so it is worth experimenting. Value Comparison ---------------- -Python has two ways to compare values ``a == b`` and ``a is b``, the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, that both variables reference the same item in memory. +Python has two ways to compare values ``a == b`` and ``a is b``, +the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, +that both variables reference the same item in memory. In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster. @@ -362,3 +390,4 @@ While developing a script it's good to time it to be aware of any changes in per # do something... print("My Script Finished: %.4f sec" % time.time() - time_start) + diff --git a/doc/python_api/rst/info_overview.rst b/doc/python_api/rst/info_overview.rst index b2d524b74af..960dd07ecf1 100644 --- a/doc/python_api/rst/info_overview.rst +++ b/doc/python_api/rst/info_overview.rst @@ -1,18 +1,25 @@ + .. _info_overview: ******************* Python API Overview ******************* -This document is to give an understanding of how python and blender fit together, covering some of the functionality that isn't obvious from reading the API reference and example scripts. +This document is to give an understanding of how Python and Blender fit together, +covering some of the functionality that isn't obvious from reading the API reference and example scripts. Python in Blender ================= -Blender embeds a python interpreter which is started with blender and stays active. This interpreter runs scripts to draw the user interface and is used for some of Blender's internal tools too. +Blender embeds a Python interpreter which is started with Blender and stays active. +This interpreter runs scripts to draw the user interface and is used for some of Blender's internal tools too. -This is a typical python environment so tutorials on how to write python scripts will work running the scripts in blender too. Blender provides the :mod:`bpy` module to the python interpreter. This module can be imported in a script and gives access to blender data, classes, and functions. Scripts that deal with blender data will need to import this module. +This is a typical Python environment so tutorials on how to write Python scripts +will work running the scripts in Blender too. +Blender provides the :mod:`bpy` module to the Python interpreter. +This module can be imported in a script and gives access to Blender data, classes, and functions. +Scripts that deal with Blender data will need to import this module. Here is a simple example of moving a vertex of the object named **Cube**: @@ -21,84 +28,96 @@ Here is a simple example of moving a vertex of the object named **Cube**: import bpy bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0 -This modifies Blender's internal data directly. When you run this in the interactive console you will see the 3D viewport update. +This modifies Blender's internal data directly. +When you run this in the interactive console you will see the 3D viewport update. The Default Environment ======================= -When developing your own scripts it may help to understand how blender sets up its python environment. Many python scripts come bundled with blender and can be used as a reference because they use the same API that script authors write tools in. Typical usage for scripts include: user interface, import/export, scene manipulation, automation, defining your own toolset and customization. +When developing your own scripts it may help to understand how Blender sets up its Python environment. +Many Python scripts come bundled with Blender and can be used as a reference +because they use the same API that script authors write tools in. +Typical usage for scripts include: user interface, import/export, +scene manipulation, automation, defining your own toolset and customization. -On startup blender scans the ``scripts/startup/`` directory for python modules and imports them. The exact location of this directory depends on your installation. `See the directory layout docs <http://wiki.blender.org/index.php/Doc:2.6/Manual/Introduction/Installing_Blender/DirectoryLayout>`_ +On startup Blender scans the ``scripts/startup/`` directory for Python modules and imports them. +The exact location of this directory depends on your installation. +`See the directory layout docs +<https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`__ Script Loading ============== -This may seem obvious but it's important to note the difference between executing a script directly or importing it as a module. - -Scripts that extend blender - define classes that exist beyond the scripts execution, this makes future access to these classes (to unregister for example) more difficult than importing as a module where class instance is kept in the module and can be accessed by importing that module later on. +This may seem obvious but it's important to note the difference +between executing a script directly or importing it as a module. -For this reason it's preferable to only use directly execute scripts that don't extend blender by registering classes. +Scripts that extend Blender - define classes that exist beyond the scripts execution, +this makes future access to these classes (to unregister for example) +more difficult than importing as a module where class instance is kept +in the module and can be accessed by importing that module later on. +For this reason it's preferable to only use directly execute scripts that don't extend Blender by registering classes. -Here are some ways to run scripts directly in blender. -* Loaded in the text editor and press **Run Script**. +Here are some ways to run scripts directly in Blender. -* Typed or pasted into the interactive console. +- Loaded in the text editor and press **Run Script**. +- Typed or pasted into the interactive console. +- Execute a Python file from the command line with Blender, eg: -* Execute a python file from the command line with blender, eg: + .. code-block:: sh - ``blender --python /home/me/my_script.py`` + blender --python /home/me/my_script.py To run as modules: -* The obvious way, ``import some_module`` command from the text window or interactive console. - -* Open as a text block and tick "Register" option, this will load with the blend file. - -* copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup. - -* define as an addon, enabling the addon will load it as a python module. +- The obvious way, ``import some_module`` command from the text window or interactive console. +- Open as a text block and tick "Register" option, this will load with the blend file. +- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup. +- define as an addon, enabling the addon will load it as a Python module. Addons ------ -Some of blenders functionality is best kept optional, alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``, and only load on startup if selected from the user preferences. +Some of Blenders functionality is best kept optional, +alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``, +and only load on startup if selected from the user preferences. -The only difference between addons and built-in python modules is that addons must contain a **bl_info** variable which blender uses to read metadata such as name, author, category and URL. +The only difference between addons and built-in Python modules is that addons must contain a ``bl_info`` +variable which Blender uses to read metadata such as name, author, category and URL. The user preferences addon listing uses **bl_info** to display information about each addon. -`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`_ for details on the **bl_info** dictionary. +`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`__ +for details on the ``bl_info`` dictionary. Integration through Classes =========================== -Running python scripts in the text editor is useful for testing but you’ll want to extend blender to make tools accessible like other built-in functionality. - -The blender python api allows integration for: +Running Python scripts in the text editor is useful for testing but you'll +want to extend Blender to make tools accessible like other built-in functionality. -* :class:`bpy.types.Panel` +The Blender Python api allows integration for: -* :class:`bpy.types.Menu` +- :class:`bpy.types.Panel` +- :class:`bpy.types.Menu` +- :class:`bpy.types.Operator` +- :class:`bpy.types.PropertyGroup` +- :class:`bpy.types.KeyingSet` +- :class:`bpy.types.RenderEngine` -* :class:`bpy.types.Operator` -* :class:`bpy.types.PropertyGroup` +This is intentionally limited. Currently, for more advanced features such as mesh modifiers, +object types, or shader nodes, C/C++ must be used. -* :class:`bpy.types.KeyingSet` - -* :class:`bpy.types.RenderEngine` - - -This is intentionally limited. Currently, for more advanced features such as mesh modifiers, object types, or shader nodes, C/C++ must be used. - -For python intergration Blender defines methods which are common to all types. This works by creating a python subclass of a Blender class which contains variables and functions specified by the parent class which are pre-defined to interface with Blender. +For Python integration Blender defines methods which are common to all types. +This works by creating a Python subclass of a Blender class which contains variables and functions +specified by the parent class which are pre-defined to interface with Blender. For example: @@ -115,15 +134,20 @@ For example: bpy.utils.register_class(SimpleOperator) -First note that we subclass a member of :mod:`bpy.types`, this is common for all classes which can be integrated with blender and used so we know if this is an Operator and not a Panel when registering. +First note that we subclass a member of :mod:`bpy.types`, +this is common for all classes which can be integrated with Blender and +used so we know if this is an Operator and not a Panel when registering. -Both class properties start with a **bl_** prefix. This is a convention used to distinguish blender properties from those you add yourself. +Both class properties start with a ``bl_`` prefix. +This is a convention used to distinguish Blender properties from those you add yourself. -Next see the execute function, which takes an instance of the operator and the current context. A common prefix is not used for functions. +Next see the execute function, which takes an instance of the operator and the current context. +A common prefix is not used for functions. -Lastly the register function is called, this takes the class and loads it into blender. See `Class Registration`_. +Lastly the register function is called, this takes the class and loads it into Blender. See `Class Registration`_. -Regarding inheritance, blender doesn't impose restrictions on the kinds of class inheritance used, the registration checks will use attributes and functions defined in parent classes. +Regarding inheritance, Blender doesn't impose restrictions on the kinds of class inheritance used, +the registration checks will use attributes and functions defined in parent classes. class mix-in example: @@ -141,11 +165,20 @@ class mix-in example: bpy.utils.register_class(SimpleOperator) -Notice these classes don't define an ``__init__(self)`` function. While ``__init__()`` and ``__del__()`` will be called if defined, the class instances lifetime only spans the execution. So a panel for example will have a new instance for every redraw, for this reason there is rarely a cause to store variables in the panel instance. Instead, persistent variables should be stored in Blenders data so that the state can be restored when blender is restarted. +Notice these classes don't define an ``__init__(self)`` function. +While ``__init__()`` and ``__del__()`` will be called if defined, +the class instances lifetime only spans the execution. +So a panel for example will have a new instance for every redraw, +for this reason there is rarely a cause to store variables in the panel instance. +Instead, persistent variables should be stored in Blenders +ata so that the state can be restored when Blender is restarted. + +.. note:: -.. note:: Modal operators are an exception, keeping their instance variable as blender runs, see modal operator template. + Modal operators are an exception, keeping their instance variable as Blender runs, see modal operator template. -So once the class is registered with blender, instancing the class and calling the functions is left up to blender. In fact you cannot instance these classes from the script as you would expect with most python API's. +So once the class is registered with Blender, instancing the class and calling the functions is left up to Blender. +In fact you cannot instance these classes from the script as you would expect with most Python API's. To run operators you can call them through the operator api, eg: @@ -154,7 +187,8 @@ To run operators you can call them through the operator api, eg: import bpy bpy.ops.object.simple_operator() -User interface classes are given a context in which to draw, buttons window, file header, toolbar etc, then they are drawn when that area is displayed so they are never called by python scripts directly. +User interface classes are given a context in which to draw, buttons window, file header, toolbar etc, +then they are drawn when that area is displayed so they are never called by Python scripts directly. Registration @@ -164,9 +198,10 @@ Registration Module Registration ------------------- -Blender modules loaded at startup require ``register()`` and ``unregister()`` functions. These are the *only* functions that blender calls from your code, which is otherwise a regular python module. +Blender modules loaded at startup require ``register()`` and ``unregister()`` functions. +These are the *only* functions that Blender calls from your code, which is otherwise a regular Python module. -A simple blender/python module can look like this: +A simple Blender/Python module can look like this: .. code-block:: python @@ -184,12 +219,16 @@ A simple blender/python module can look like this: if __name__ == "__main__": register() -These functions usually appear at the bottom of the script containing class registration sometimes adding menu items. You can also use them for internal purposes setting up data for your own tools but take care since register won't re-run when a new blend file is loaded. +These functions usually appear at the bottom of the script containing class registration sometimes adding menu items. +You can also use them for internal purposes setting up data for your own tools but take care +since register won't re-run when a new blend file is loaded. -The register/unregister calls are used so it's possible to toggle addons and reload scripts while blender runs. -If the register calls were placed in the body of the script, registration would be called on import, meaning there would be no distinction between importing a module or loading its classes into blender. +The register/unregister calls are used so it's possible to toggle addons and reload scripts while Blender runs. +If the register calls were placed in the body of the script, registration would be called on import, +meaning there would be no distinction between importing a module or loading its classes into Blender. -This becomes problematic when a script imports classes from another module making it difficult to manage which classes are being loaded and when. +This becomes problematic when a script imports classes from another module +making it difficult to manage which classes are being loaded and when. The last 2 lines are only for testing: @@ -199,19 +238,24 @@ The last 2 lines are only for testing: register() This allows the script to be run directly in the text editor to test changes. -This ``register()`` call won't run when the script is imported as a module since ``__main__`` is reserved for direct execution. +This ``register()`` call won't run when the script is imported as a module +since ``__main__`` is reserved for direct execution. Class Registration ------------------ -Registering a class with blender results in the class definition being loaded into blender, where it becomes available alongside existing functionality. +Registering a class with Blender results in the class definition being loaded into Blender, +where it becomes available alongside existing functionality. -Once this class is loaded you can access it from :mod:`bpy.types`, using the bl_idname rather than the classes original name. +Once this class is loaded you can access it from :mod:`bpy.types`, +using the bl_idname rather than the classes original name. -When loading a class, blender performs sanity checks making sure all required properties and functions are found, that properties have the correct type, and that functions have the right number of arguments. +When loading a class, Blender performs sanity checks making sure all required properties and functions are found, +that properties have the correct type, and that functions have the right number of arguments. -Mostly you will not need concern yourself with this but if there is a problem with the class definition it will be raised on registering: +Mostly you will not need concern yourself with this but if there is a problem +with the class definition it will be raised on registering: Using the function arguments ``def execute(self, context, spam)``, will raise an exception: @@ -225,9 +269,13 @@ Using ``bl_idname = 1`` will raise. Multiple-Classes ^^^^^^^^^^^^^^^^ -Loading classes into blender is described above, for simple cases calling :mod:`bpy.utils.register_class` (SomeClass) is sufficient, but when there are many classes or a packages submodule has its own classes it can be tedious to list them all for registration. +Loading classes into Blender is described above, +for simple cases calling :mod:`bpy.utils.register_class` (SomeClass) is sufficient, +but when there are many classes or a packages submodule has its own +classes it can be tedious to list them all for registration. -For more convenient loading/unloading :mod:`bpy.utils.register_module` (module) and :mod:`bpy.utils.unregister_module` (module) functions exist. +For more convenient loading/unloading :mod:`bpy.utils.register_module` (module) +and :mod:`bpy.utils.unregister_module` (module) functions exist. A script which defines many of its own operators, panels menus etc. you only need to write: @@ -239,13 +287,19 @@ A script which defines many of its own operators, panels menus etc. you only nee def unregister(): bpy.utils.unregister_module(__name__) -Internally blender collects subclasses on registrable types, storing them by the module in which they are defined. By passing the module name to :mod:`bpy.utils.register_module` blender can register all classes created by this module and its submodules. +Internally Blender collects subclasses on registrable types, storing them by the module in which they are defined. +By passing the module name to :mod:`bpy.utils.register_module` +Blender can register all classes created by this module and its submodules. Inter Classes Dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^ -When customizing blender you may want to group your own settings together, after all, they will likely have to co-exist with other scripts. To group these properties classes need to be defined, for groups within groups or collections within groups you can find yourself having to deal with order of registration/unregistration. +When customizing Blender you may want to group your own settings together, +after all, they will likely have to co-exist with other scripts. +To group these properties classes need to be defined, +for groups within groups or collections within groups +you can find yourself having to deal with order of registration/unregistration. Custom properties groups are themselves classes which need to be registered. @@ -311,7 +365,9 @@ Say you want to store material settings for a custom engine. Manipulating Classes ^^^^^^^^^^^^^^^^^^^^ -Properties can be added and removed as blender runs, normally happens on register or unregister but for some special cases it may be useful to modify types as the script runs. +Properties can be added and removed as Blender runs, +normally happens on register or unregister but for some +special cases it may be useful to modify types as the script runs. For example: @@ -341,7 +397,8 @@ This works just as well for PropertyGroup subclasses you define yourself. Dynamic Defined-Classes (Advanced) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In some cases the specifier for data may not be in blender, renderman shader definitions for example and it may be useful to define types and remove them on the fly. +In some cases the specifier for data may not be in Blender, +renderman shader definitions for example and it may be useful to define types and remove them on the fly. .. code-block:: python @@ -360,7 +417,8 @@ In some cases the specifier for data may not be in blender, renderman shader def .. note:: - Notice ``type()`` is called to define the class. This is an alternative syntax for class creation in python, better suited to constructing classes dynamically. + ``type()`` is called to define the class. + This is an alternative syntax for class creation in Python, better suited to constructing classes dynamically. Calling these operators: diff --git a/doc/python_api/rst/info_quickstart.rst b/doc/python_api/rst/info_quickstart.rst index dc1bba01f00..8ded6e6fae0 100644 --- a/doc/python_api/rst/info_quickstart.rst +++ b/doc/python_api/rst/info_quickstart.rst @@ -1,3 +1,4 @@ + .. _info_quickstart: *********************** @@ -32,13 +33,15 @@ The Blender/Python API **can't** (yet)... Before Starting =============== -This document isn't intended to fully cover each topic. Rather, its purpose is to familiarize you with Blender Python API. +This document isn't intended to fully cover each topic. +Rather, its purpose is to familiarize you with Blender Python API. A quick list of helpful things to know before starting: - Blender uses Python 3.x; some online documentation still assumes 2.x. -- The interactive console is great for testing one-liners, It also has autocompletion so you can inspect the API quickly. +- The interactive console is great for testing one-liners. + It also has autocompletion so you can inspect the API quickly. - Button tool tips show Python attributes and operator names. - Right clicking on buttons and menu items directly links to API documentation. - For more examples, the text menu has a templates section where some example operators can be found. @@ -51,15 +54,19 @@ A quick list of helpful things to know before starting: Running Scripts --------------- -The two most common ways to execute Python scripts are using the built-in text editor or entering commands in the Python console. +The two most common ways to execute Python scripts are using the built-in +text editor or entering commands in the Python console. -Both the **Text Editor** and **Python Console** are space types you can select from the view header. +Both the *Text Editor* and *Python Console* are space types you can select from the view header. -Rather then manually configuring your spaces for Python development, you may prefer to use the **Scripting** screen, included default with Blender, accessible from the top headers screen selector. +Rather then manually configuring your spaces for Python development, +you may prefer to use the *Scripting* screen, included default with Blender, +accessible from the top headers screen selector. -From the text editor you can open ``.py`` files or paste then from the clipboard, then test using **Run Script**. +From the text editor you can open ``.py`` files or paste then from the clipboard, then test using *Run Script*. -The Python Console is typically used for typing in snippets and for testing to get immediate feedback, but can also have entire scripts pasted into it. +The Python Console is typically used for typing in snippets and for testing to get immediate feedback, +but can also have entire scripts pasted into it. Scripts can also run from the command line with Blender but to learn Blender/Python this isn't essential. @@ -73,9 +80,11 @@ Data Access Accessing DataBlocks ^^^^^^^^^^^^^^^^^^^^ -Python accesses Blender's data in the same way as the animation system and user interface; this implies that any setting that can be changed via a button can also be changed from Python. +Python accesses Blender's data in the same way as the animation system and user interface; +this implies that any setting that can be changed via a button can also be changed from Python. -Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`. This gives access to library data. For example: +Accessing data from the currently loaded blend file is done with the module :mod:`bpy.data`. +This gives access to library data. For example: >>> bpy.data.objects <bpy_collection[3], BlendDataObjects> @@ -92,7 +101,8 @@ About Collections You'll notice that an index as well as a string can be used to access members of the collection. -Unlike Python's dictionaries, both methods are acceptable; however, the index of a member may change while running Blender. +Unlike Python's dictionaries, both methods are acceptable; +however, the index of a member may change while running Blender. >>> list(bpy.data.objects) [bpy.data.objects["Cube"], bpy.data.objects["Plane"]] @@ -107,7 +117,10 @@ Unlike Python's dictionaries, both methods are acceptable; however, the index of Accessing Attributes ^^^^^^^^^^^^^^^^^^^^ -Once you have a data block, such as a material, object, groups etc., its attributes can be accessed much like you would change a setting using the graphical interface. In fact, the tooltip for each button also displays the Python attribute which can help in finding what settings to change in a script. +Once you have a data block, such as a material, object, groups etc., +its attributes can be accessed much like you would change a setting using the graphical interface. +In fact, the tooltip for each button also displays the Python attribute +which can help in finding what settings to change in a script. >>> bpy.data.objects[0].name 'Camera' @@ -119,7 +132,8 @@ Once you have a data block, such as a material, object, groups etc., its attribu bpy.data.materials['MyMaterial'] -For testing what data to access it's useful to use the "Console", which is its own space type. This supports auto-complete, giving you a fast way to dig into different data in your file. +For testing what data to access it's useful to use the "Console", which is its own space type. +This supports auto-complete, giving you a fast way to dig into different data in your file. Example of a data path that can be quickly found via the console: @@ -132,7 +146,8 @@ Example of a data path that can be quickly found via the console: Data Creation/Removal ^^^^^^^^^^^^^^^^^^^^^ -Those of you familiar with other Python API's may be surprised that new datablocks in the bpy API can't be created by calling the class: +Those of you familiar with other Python API's may be surprised that +new datablocks in the bpy API can't be created by calling the class: >>> bpy.types.Mesh() Traceback (most recent call last): @@ -141,7 +156,8 @@ Those of you familiar with other Python API's may be surprised that new databloc This is an intentional part of the API design. -The Blender/Python API can't create Blender data that exists outside the main Blender database (accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc). +The Blender/Python API can't create Blender data that exists outside the main Blender database +(accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc). Data is added and removed via methods on the collections in :mod:`bpy.data`, eg: @@ -155,8 +171,10 @@ Data is added and removed via methods on the collections in :mod:`bpy.data`, eg: Custom Properties ^^^^^^^^^^^^^^^^^ -Python can access properties on any datablock that has an ID (data that can be linked in and accessed from :mod:`bpy.data`. -When assigning a property, you can make up your own names, these will be created when needed or overwritten if they exist. +Python can access properties on any datablock that has an ID +(data that can be linked in and accessed from :mod:`bpy.data`. +When assigning a property, you can make up your own names, +these will be created when needed or overwritten if they exist. This data is saved with the blend file and copied with objects. @@ -192,8 +210,10 @@ These properties are valid outside of Python. They can be animated by curves or Context ------- -While it's useful to be able to access data directly by name or as a list, it's more common to operate on the user's selection. -The context is always available from ``bpy.context`` and can be used to get the active object, scene, tool settings along with many other attributes. +While it's useful to be able to access data directly by name or as a list, +it's more common to operate on the user's selection. +The context is always available from ``bpy.context`` and can be used to get the active object, scene, +tool settings along with many other attributes. Common-use cases: @@ -201,7 +221,9 @@ Common-use cases: >>> bpy.context.selected_objects >>> bpy.context.visible_bones -Note that the context is read-only. These values cannot be modified directly, though they may be changed by running API functions or by using the data API. +Note that the context is read-only. +These values cannot be modified directly, +though they may be changed by running API functions or by using the data API. So ``bpy.context.object = obj`` will raise an error. @@ -209,7 +231,8 @@ But ``bpy.context.scene.objects.active = obj`` will work as expected. The context attributes change depending on where they are accessed. -The 3D view has different context members than the console, so take care when accessing context attributes that the user state is known. +The 3D view has different context members than the console, +so take care when accessing context attributes that the user state is known. See :mod:`bpy.context` API reference. @@ -217,7 +240,9 @@ See :mod:`bpy.context` API reference. Operators (Tools) ----------------- -Operators are tools generally accessed by the user from buttons, menu items or key shortcuts. From the user perspective they are a tool but Python can run these with its own settings through the :mod:`bpy.ops` module. +Operators are tools generally accessed by the user from buttons, menu items or key shortcuts. +From the user perspective they are a tool but Python can run these with its own settings +through the :mod:`bpy.ops` module. Examples: @@ -230,14 +255,16 @@ Examples: .. note:: - The menu item: :menuselection:`Help --> Operator Cheat Sheet` gives a list of all operators and their default values in Python syntax, along with the generated docs. + The menu item: :menuselection:`Help --> Operator Cheat Sheet` + gives a list of all operators and their default values in Python syntax, along with the generated docs. This is a good way to get an overview of all Blender's operators. Operator Poll() ^^^^^^^^^^^^^^^ -Many operators have a "poll" function which may check that the mouse is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc). +Many operators have a "poll" function which may check that the cursor +is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc). When an operator's poll function fails within Python, an exception is raised. For example, calling ``bpy.ops.view3d.render_border()`` from the console raises the following error: @@ -248,7 +275,8 @@ For example, calling ``bpy.ops.view3d.render_border()`` from the console raises In this case the context must be the 3d view with an active camera. -To avoid using try/except clauses wherever operators are called you can call the operators own .poll() function to check if it can run in the current context. +To avoid using try/except clauses wherever operators are called you can call the operators +own ``poll()`` function to check if it can run in the current context. .. code-block:: python @@ -275,7 +303,8 @@ Example Operator .. literalinclude:: ../../../release/scripts/templates_py/operator_simple.py -Once this script runs, ``SimpleOperator`` is registered with Blender and can be called from the operator search popup or added to the toolbar. +Once this script runs, ``SimpleOperator`` is registered with Blender +and can be called from the operator search popup or added to the toolbar. To run the script: @@ -285,19 +314,23 @@ To run the script: #. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block. #. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame). #. Click on the button **Run Script**. -#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple". +#. Move your cursor into the 3D view, press spacebar for the operator search menu, and type "Simple". #. Click on the "Simple Operator" item found in search. .. seealso:: The class members with the ``bl_`` prefix are documented in the API reference :class:`bpy.types.Operator` -.. note:: The output from the ``main`` function is sent to the terminal; in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`. +.. note:: + + The output from the ``main`` function is sent to the terminal; + in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`. Example Panel ------------- -Panels register themselves as a class, like an operator. Notice the extra ``bl_`` variables used to set the context they display in. +Panels register themselves as a class, like an operator. +Notice the extra ``bl_`` variables used to set the context they display in. .. literalinclude:: ../../../release/scripts/templates_py/ui_panel_simple.py @@ -334,7 +367,8 @@ Blender's Python API can be split up into 3 categories. Native Types ------------ -In simple cases returning a number or a string as a custom type would be cumbersome, so these are accessed as normal Python types. +In simple cases returning a number or a string as a custom type would be cumbersome, +so these are accessed as normal Python types. - Blender float/int/boolean -> float/int/boolean - Blender enumerator -> string @@ -359,7 +393,8 @@ Used for Blender datablocks and collections: :class:`bpy.types.bpy_struct` For data that contains its own attributes groups/meshes/bones/scenes... etc. -There are 2 main types that wrap Blenders data, one for datablocks (known internally as ``bpy_struct``), another for properties. +There are 2 main types that wrap Blenders data, one for datablocks +(known internally as ``bpy_struct``), another for properties. >>> bpy.context.object bpy.data.objects['Cube'] @@ -375,7 +410,9 @@ Mathutils Types Used for vectors, quaternion, eulers, matrix and color types, accessible from :mod:`mathutils` -Some attributes such as :class:`bpy.types.Object.location`, :class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location` can be accessed as special math types which can be used together and manipulated in various useful ways. +Some attributes such as :class:`bpy.types.Object.location`, +:class:`bpy.types.PoseBone.rotation_euler` and :class:`bpy.types.Scene.cursor_location` +can be accessed as special math types which can be used together and manipulated in various useful ways. Example of a matrix, vector multiplication: @@ -410,7 +447,9 @@ Animation There are 2 ways to add keyframes through Python. -The first is through key properties directly, which is similar to inserting a keyframe from the button as a user. You can also manually create the curves and keyframe data, then set the path to the property. Here are examples of both methods. +The first is through key properties directly, which is similar to inserting a keyframe from the button as a user. +You can also manually create the curves and keyframe data, then set the path to the property. +Here are examples of both methods. Both examples insert a keyframe on the active object's Z axis. diff --git a/doc/python_api/rst/info_tips_and_tricks.rst b/doc/python_api/rst/info_tips_and_tricks.rst index e345f36a148..da213e32a78 100644 --- a/doc/python_api/rst/info_tips_and_tricks.rst +++ b/doc/python_api/rst/info_tips_and_tricks.rst @@ -1,10 +1,12 @@ + *************** Tips and Tricks *************** Here are various suggestions that you might find useful when writing scripts. -Some of these are just python features that scripters may not have thought to use with blender, others are blender specific. +Some of these are just Python features that scripters may not have thought to use with Blender, +others are Blender specific. .. _use_the_terminal: @@ -12,18 +14,21 @@ Some of these are just python features that scripters may not have thought to us Use The Terminal ================ -When writing python scripts, it's useful to have a terminal open, this is not the built-in python console but a terminal application which is used to start blender. +When writing Python scripts, it's useful to have a terminal open, +this is not the built-in Python console but a terminal application which is used to start Blender. There are 3 main uses for the terminal, these are: -* You can see the output of ``print()`` as your script runs, which is useful to view debug info. - -* The error trace-back is printed in full to the terminal which won't always generate an error popup in blender's user interface (depending on how the script is executed). - -* If the script runs for too long or you accidentally enter an infinite loop, Ctrl+C in the terminal (Ctrl+Break on Windows) will quit the script early. +- You can see the output of ``print()`` as your script runs, which is useful to view debug info. +- The error trace-back is printed in full to the terminal which won't always generate an error popup in + Blender's user interface (depending on how the script is executed). +- If the script runs for too long or you accidentally enter an infinite loop, + :kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early. .. note:: - For Linux and OSX users this means starting the terminal first, then running blender from within it. On Windows the terminal can be enabled from the help menu. + + For Linux and OSX users this means starting the terminal first, then running Blender from within it. + On Windows the terminal can be enabled from the help menu. Interface Tricks @@ -33,43 +38,56 @@ Interface Tricks Access Operator Commands ------------------------ -You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops``... command to run that button, a handy (hidden) feature is that you can press Ctrl+C over any menu item/button to copy this command into the clipboard. +You may have noticed that the tooltip for menu items and buttons includes the ``bpy.ops.[...])`` command +to run that button, a handy (hidden) feature is that you can press :kbd:`Ctrl-C` over +any menu item/button to copy this command into the clipboard. Access Data Path ---------------- -To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away. To get this quickly you can right click on the setting and select select **Copy Data Path**, +To find the path from an :class:`ID` datablock to its setting isn't always so simple since it may be nested away. +To get this quickly you can right click on the setting and select select **Copy Data Path**, if this can't be generated, only the property name is copied. .. note:: - This uses the same method for creating the animation path used by :class:`bpy.types.FCurve.data_path` and :class:`bpy.types.DriverTarget.data_path` drivers. + This uses the same method for creating the animation path used by + :class:`bpy.types.FCurve.data_path` and + :class:`bpy.types.DriverTarget.data_path` drivers. -.. _info_show_all_operators +.. _info_show_all_operators: Show All Operators ================== -While blender logs operators in the Info space, this only reports operators with the ``REGISTER`` option enabeld so as not to flood the Info view with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``. +While Blender logs operators in the Info space, +this only reports operators with the ``REGISTER`` option enabeld so as not to flood the *Info* view +with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``. -However, for testing it can be useful to see **every** operator called in a terminal, do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting blender or by setting :mod:`bpy.app.debug_wm` to True while blender is running. +However, for testing it can be useful to see **every** operator called in a terminal, +do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting Blender +or by setting :mod:`bpy.app.debug_wm` to ``True`` while Blender is running. Use an External Editor ====================== -Blenders text editor is fine for small changes and writing tests but its not full featured, for larger projects you'll probably want to use a standalone editor or python IDE. +Blenders text editor is fine for small changes and writing tests but its not full featured, +for larger projects you'll probably want to use a standalone editor or Python IDE. -Editing a text file externally and having the same text open in blender does work but isn't that optimal so here are 2 ways you can easily use an external file from blender. +Editing a text file externally and having the same text open in Blender does work but isn't that optimal +so here are 2 ways you can easily use an external file from Blender. + +Using the following examples you'll still need textblock in Blender to execute, +but reference an external file rather then including it directly. -Using the following examples you'll still need textblock in blender to execute, but reference an external file rather then including it directly. Executing External Scripts -------------------------- -This is the equivalent to running the script directly, referencing a scripts path from a 2 line textblock. +This is the equivalent to running the script directly, referencing a scripts path from a 2 line text-block. .. code-block:: python @@ -102,12 +120,17 @@ This example shows loading a script in as a module and executing a module functi myscript.main() -Notice that the script is reloaded every time, this forces use of the modified version, otherwise the cached one in ``sys.modules`` would be used until blender was restarted. +Notice that the script is reloaded every time, this forces use of the modified version, +otherwise the cached one in ``sys.modules`` would be used until Blender was restarted. -The important difference between this and executing the script directly is it has to call a function in the module, in this case ``main()`` but it can be any function, an advantage with this is you can pass arguments to the function from this small script which is often useful for testing different settings quickly. +The important difference between this and executing the script directly is it +has to call a function in the module, in this case ``main()`` but it can be any function, +an advantage with this is you can pass arguments to the function from this +small script which is often useful for testing different settings quickly. -The other issue with this is the script has to be in pythons module search path. -While this is not best practice - for testing you can extend the search path, this example adds the current blend files directory to the search path, then loads the script as a module. +The other issue with this is the script has to be in Pythons module search path. +While this is not best practice - for testing you can extend the search path, +this example adds the current blend files directory to the search path, then loads the script as a module. .. code-block:: python @@ -128,71 +151,86 @@ While this is not best practice - for testing you can extend the search path, th Don't Use Blender! ================== -While developing your own scripts blenders interface can get in the way, manually reloading, running the scripts, opening file import etc. adds overhead. +While developing your own scripts Blenders interface can get in the way, +manually reloading, running the scripts, opening file import etc. adds overhead. -For scripts that are not interactive it can end up being more efficient not to use blenders interface at all and instead execute the script on the command line. +For scripts that are not interactive it can end up being more efficient not to use +Blenders interface at all and instead execute the script on the command line. -.. code-block:: python +.. code-block:: sh blender --background --python myscript.py You might want to run this with a blend file so the script has some data to operate on. -.. code-block:: python +.. code-block:: sh blender myscene.blend --background --python myscript.py .. note:: - Depending on your setup you might have to enter the full path to the blender executable. - + Depending on your setup you might have to enter the full path to the Blender executable. -Once the script is running properly in background mode, you'll want to check the output of the script, this depends completely on the task at hand however here are some suggestions. -* render the output to an image, use an image viewer and keep writing over the same image each time. +Once the script is running properly in background mode, you'll want to check the output of the script, +this depends completely on the task at hand however here are some suggestions. -* save a new blend file, or export the file using one of blenders exporters. +- render the output to an image, use an image viewer and keep writing over the same image each time. +- save a new blend file, or export the file using one of Blenders exporters. +- if the results can be displayed as text - print them or write them to a file. -* if the results can be displayed as text - print them or write them to a file. - -This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave your text editor to see changes. +While this can take a little time to setup, it can be well worth the effort +to reduce the time it takes to test changes - you can even have +Blender running the script every few seconds with a viewer updating the results, +so no need to leave your text editor to see changes. Use External Tools ================== -When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on your data and read the result back in. +When there are no readily available Python modules to perform specific tasks it's +worth keeping in mind you may be able to have Python execute an external command +on your data and read the result back in. -Using external programs adds an extra dependency and may limit who can use the script but to quickly setup your own custom pipeline or writing one-off scripts this can be handy. +Using external programs adds an extra dependency and may limit who can use the script +but to quickly setup your own custom pipeline or writing one-off scripts this can be handy. Examples include: -* Run The Gimp in batch mode to execute custom scripts for advanced image processing. - -* Write out 3D models to use external mesh manipulation tools and read back in the results. - -* Convert files into recognizable formats before reading. +- Run The Gimp in batch mode to execute custom scripts for advanced image processing. +- Write out 3D models to use external mesh manipulation tools and read back in the results. +- Convert files into recognizable formats before reading. Bundled Python & Extensions =========================== -The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in your systems python wont be found by blender. +The Blender releases distributed from blender.org include a complete Python installation on all platforms, +this has the disadvantage that any extensions you have installed in your systems Python wont be found by Blender. There are 2 ways around this: -* remove blender python sub-directory, blender will then fallback on the systems python and use that instead **python version must match the one that blender comes with**. +- remove Blender Python sub-directory, Blender will then fallback on the systems Python and use that instead + .. warning:: + + The Python version must match the one that Blender comes with. -* copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on. +- copy the extensions into Blender's Python sub-directory so Blender can access them, + you could also copy the entire Python installation into Blenders sub-directory, + replacing the one Blender comes with. + This works as long as the Python versions match and the paths are created in the same relative locations. + Doing this has the advantage that you can redistribute this bundle to others with Blender and/or the game player, + including any extensions you rely on. Drop Into a Python Interpreter in Your Script ============================================= -In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on. +In the middle of a script you may want to inspect some variables, +run some function and generally dig about to see whats going on. .. code-block:: python @@ -217,10 +255,13 @@ The next example is an equivalent single line version of the script above which __import__('code').interact(local=dict(globals(), **locals())) -``code.interact`` can be added at any line in the script and will pause the script an launch an interactive interpreter in the terminal, when you're done you can quit the interpreter and the script will continue execution. +``code.interact`` can be added at any line in the script +and will pause the script an launch an interactive interpreter in the terminal, +when you're done you can quit the interpreter and the script will continue execution. -If you have **IPython** installed you can use their ``embed()`` function which will implicitly use the current namespace, this has autocomplete and some useful features that the standard python eval-loop doesn't have. +If you have **IPython** installed you can use its ``embed()`` function which uses the current namespace. +The IPython prompt has auto-complete and some useful features that the standard Python eval-loop doesn't have. .. code-block:: python @@ -228,7 +269,7 @@ If you have **IPython** installed you can use their ``embed()`` function which w IPython.embed() -Admittedly this highlights the lack of any python debugging support built into blender, but its still handy to know. +Admittedly this highlights the lack of any Python debugging support built into Blender, but its still handy to know. .. note:: @@ -242,27 +283,32 @@ Advanced Blender as a module ------------------- -From a python perspective it's nicer to have everything as an extension which lets the python script combine many components. +From a Python perspective it's nicer to have everything as an extension +which lets the Python script combine many components. Advantages include: -* you can use external editors/IDE's with blenders python API and execute scripts within the IDE (step over code, inspect variables as the script runs). +- you can use external editors/IDE's with Blenders Python API and execute scripts within the IDE + (step over code, inspect variables as the script runs). +- editors/IDE's can auto complete Blender modules & variables. +- existing scripts can import Blender API's without having to run inside Blender. -* editors/IDE's can auto complete blender modules & variables. -* existing scripts can import blender API's without having to run inside blender. +This is marked advanced because to run Blender as a Python module requires a special build option. - -This is marked advanced because to run blender as a python module requires a special build option. - -For instructions on building see `Building blender as a python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_ +For instructions on building see +`Building Blender as a Python module <http://wiki.blender.org/index.php/User:Ideasman42/BlenderAsPyModule>`_ Python Safety (Build Option) ---------------------------- -Since it's possible to access data which has been removed (see Gotcha's), this can be hard to track down the cause of crashes. +Since it's possible to access data which has been removed (see Gotcha's), +this can be hard to track down the cause of crashes. + +To raise Python exceptions on accessing freed data (rather then crashing), +enable the CMake build option WITH_PYTHON_SAFETY. -To raise python exceptions on accessing freed data (rather then crashing), enable the CMake build option WITH_PYTHON_SAFETY. +This enables data tracking which makes data access about 2x slower +which is why the option isn't enabled in release builds. -This enables data tracking which makes data access about 2x slower which is why the option is not enabled in release builds. diff --git a/doc/python_api/rst/info_tutorial_addon.rst b/doc/python_api/rst/info_tutorial_addon.rst index 659b80df632..239c28859a3 100644 --- a/doc/python_api/rst/info_tutorial_addon.rst +++ b/doc/python_api/rst/info_tutorial_addon.rst @@ -208,6 +208,7 @@ The objects should move as before. *Keep this addon open in Blender for the next step - Installing.* + Install The Addon ----------------- @@ -221,10 +222,11 @@ restrictions that apply to Python modules and end with a ``.py`` extension. Once the file is on disk, you can install it as you would for an addon downloaded online. -Open the user **File -> User Preferences**, Select the **Addon** section, press **Install Addon...** and select the file. +Open the user :menuselection:`File -> User Preferences`, +Select the *Addon* section, press *Install Addon...* and select the file. -Now the addon will be listed and you can enable it by pressing the check-box, if you want it to be enabled on restart, -press **Save as Default**. +Now the addon will be listed and you can enable it by pressing the check-box, +if you want it to be enabled on restart, press *Save as Default*. .. note:: @@ -238,7 +240,7 @@ press **Save as Default**. print(addon_utils.paths()) More is written on this topic here: - `Directory Layout <http://wiki.blender.org/index.php/Doc:2.6/Manual/Introduction/Installing_Blender/DirectoryLayout>`_ + `Directory Layout <https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`_ Your Second Addon |