Welcome to mirror list, hosted at ThFree Co, Russian Federation.

info_quickstart.rst « rst « python_api « doc - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ab106dd3bb777d86e28437a4c88ae7803cd1f6d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

.. _info_quickstart:

***********************
Quickstart Introduction
***********************

Preface
=======

This API is generally stable but some areas are still being added and improved.

The Blender/Python API can do the following:

- Edit any data the user interface can (Scenes, Meshes, Particles etc.)
- Modify user preferences, keymaps and themes
- Run tools with own settings
- Create user interface elements such as menus, headers and panels
- Create new tools
- Create interactive tools
- Create new rendering engines that integrate with Blender
- Define new settings in existing Blender data
- Draw in the 3D view using OpenGL commands from Python


The Blender/Python API **can't** (yet)...

- Create new space types.
- Assign custom properties to every type.
- Define callbacks or listeners to be notified when data is changed.


Before Starting
===============

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.
- 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.
- To examine further scripts distributed with Blender, see:

  | ``~/.blender/scripts/startup/bl_ui`` for the user interface,
  | ``~/.blender/scripts/startup/bl_op`` for operators.


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.

Both the *Text Editor* and *Python Console* are space types you can select from the view header.

Rather than 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*.

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.


Key Concepts
============

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.

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>

   >>> bpy.data.scenes
   <bpy_collection[1], BlendDataScenes>

   >>> bpy.data.materials
   <bpy_collection[1], BlendDataMaterials>


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.

   >>> list(bpy.data.objects)
   [bpy.data.objects["Cube"], bpy.data.objects["Plane"]]

   >>> bpy.data.objects['Cube']
   bpy.data.objects["Cube"]

   >>> bpy.data.objects[0]
   bpy.data.objects["Cube"]


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.

   >>> bpy.data.objects[0].name 
   'Camera'

   >>> bpy.data.scenes["Scene"]
   bpy.data.scenes['Scene']

   >>> bpy.data.materials.new("MyMaterial")
   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.

Example of a data path that can be quickly found via the console:

   >>> bpy.data.scenes[0].render.resolution_percentage
   100
   >>> bpy.data.scenes[0].objects["Torus"].data.vertices[0].co.x
   1.0


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:

   >>> bpy.types.Mesh()
   Traceback (most recent call last):
     File "<blender_console>", line 1, in <module>
   TypeError: bpy_struct.__new__(type): expected a single argument


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).

Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:

   >>> mesh = bpy.data.meshes.new(name="MyMesh")
   >>> print(mesh)
   <bpy_struct, Mesh("MyMesh.001")>

   >>> bpy.data.meshes.remove(mesh)


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.

This data is saved with the blend file and copied with objects.

Example:

.. code-block:: python

   bpy.context.object["MyOwnProperty"] = 42

   if "SomeProp" in bpy.context.object:
       print("Property found")

   # Use the get function like a Python dictionary
   # which can have a fallback value.
   value = bpy.data.scenes["Scene"].get("test_prop", "fallback value")

   # dictionaries can be assigned as long as they only use basic types.
   group = bpy.data.groups.new("MyTestGroup")
   group["GameSettings"] = {"foo": 10, "bar": "spam", "baz": {}}

   del group["GameSettings"]


Note that these properties can only be assigned  basic Python types.

- int, float, string
- array of ints/floats
- dictionary (only string keys are supported, values must be basic types too)

These properties are valid outside of Python. They can be animated by curves or used in driver paths.


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.

Common-use cases:

   >>> bpy.context.object
   >>> 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.

So ``bpy.context.object = obj`` will raise an error.

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.

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.

Examples:

   >>> bpy.ops.mesh.flip_normals()
   {'FINISHED'}
   >>> bpy.ops.mesh.hide(unselected=False)
   {'FINISHED'}
   >>> bpy.ops.object.scale_apply()
   {'FINISHED'}

.. 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.
   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 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:

.. code-block:: python

   RuntimeError: Operator bpy.ops.view3d.render_border.poll() failed, context is incorrect

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.

.. code-block:: python

   if bpy.ops.view3d.render_border.poll():
       bpy.ops.view3d.render_border()


Integration
===========

Python scripts can integrate with Blender in the following ways:

- By defining a rendering engine.
- By defining operators.
- By defining menus, headers and panels.
- By inserting new buttons into existing menus, headers and panels


In Python, this is done by defining a class, which is a subclass of an existing type.


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.

To run the script:

#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
#. Start Blender
#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout.
#. 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 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>`.

Example Panel
-------------

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

To run the script:

#. Highlight the above code then press :kbd:`Ctrl-C` to copy it
#. Start Blender
#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout
#. 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**.


To view the results:

#. Select the the default cube.
#. Click on the Object properties icon in the buttons panel (far right; appears as a tiny cube).
#. Scroll down to see a panel named **Hello World Panel**.
#. Changing the object name also updates **Hello World Panel's** Name: field.

Note the row distribution and the label and properties that are available through the code.

.. seealso:: :class:`bpy.types.Panel`


Types
=====

Blender defines a number of Python types but also uses Python native types.

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.

- Blender float/int/boolean -> float/int/boolean
- Blender enumerator -> string

     >>> C.object.rotation_mode = 'AXIS_ANGLE'

- Blender enumerator (multiple) -> set of strings

  .. code-block:: python

     # setting multiple camera overlay guides
     bpy.context.scene.camera.data.show_guide = {'GOLDEN', 'CENTER'}

     # passing as an operator argument for report types
     self.report({'WARNING', 'INFO'}, "Some message!")


Internal Types
--------------

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.

   >>> bpy.context.object
   bpy.data.objects['Cube']

   >>> C.scene.objects
   bpy.data.scenes['Scene'].objects

Note that these types reference Blender's data so modifying them is immediately visible.


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.

Example of a matrix, vector multiplication:

.. code-block:: python

   bpy.context.object.matrix_world * bpy.context.object.data.verts[0].co

.. note::

   mathutils types keep a reference to Blender's internal data so changes can
   be applied back.


   Example:

   .. code-block:: python

      # modifies the Z axis in place.
      bpy.context.object.location.z += 2.0

      # location variable holds a reference to the object too.
      location = bpy.context.object.location
      location *= 2.0

      # Copying the value drops the reference so the value can be passed to
      # functions and modified without unwanted side effects.
      location = bpy.context.object.location.copy()


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.

Both examples insert a keyframe on the active object's Z axis.

Simple example:

.. code-block:: python

   obj = bpy.context.object
   obj.location[2] = 0.0
   obj.keyframe_insert(data_path="location", frame=10.0, index=2)
   obj.location[2] = 1.0
   obj.keyframe_insert(data_path="location", frame=20.0, index=2)

Using Low-Level Functions:

.. code-block:: python

   obj = bpy.context.object
   obj.animation_data_create()
   obj.animation_data.action = bpy.data.actions.new(name="MyAction")
   fcu_z = obj.animation_data.action.fcurves.new(data_path="location", index=2)
   fcu_z.keyframe_points.add(2)
   fcu_z.keyframe_points[0].co = 10.0, 0.0
   fcu_z.keyframe_points[1].co = 20.0, 1.0