2012-03-13 06:22:43 +00:00
|
|
|
..
|
2020-06-23 13:08:49 +00:00
|
|
|
This document is appended to the auto generated BMesh API doc to avoid clogging up the C files with details.
|
2012-03-13 06:22:43 +00:00
|
|
|
to test this run:
|
2016-06-12 00:05:35 +00:00
|
|
|
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py -- \
|
|
|
|
--partial bmesh* ; cd doc/python_api ; sphinx-build sphinx-in sphinx-out ; cd ../../
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
2017-06-14 19:22:26 +00:00
|
|
|
Introduction
|
|
|
|
------------
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
This API gives access the Blender's internal mesh editing API, featuring geometry connectivity data and
|
2012-03-13 06:22:43 +00:00
|
|
|
access to editing operations such as split, separate, collapse and dissolve.
|
|
|
|
The features exposed closely follow the C API,
|
2020-06-23 13:08:49 +00:00
|
|
|
giving Python access to the functions used by Blender's own mesh editing tools.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
For an overview of BMesh data types and how they reference each other see:
|
2020-06-23 13:08:49 +00:00
|
|
|
`BMesh Design Document <https://wiki.blender.org/index.php/Dev:Source/Modeling/BMesh/Design>`__.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
**Disk** and **Radial** data is not exposed by the Python API since this is for internal use only.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
2016-10-25 15:32:58 +00:00
|
|
|
.. warning:: TODO items are...
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
- add access to BMesh **walkers**.
|
|
|
|
- add custom-data manipulation functions add, remove or rename.
|
2012-03-21 05:33:37 +00:00
|
|
|
|
2016-10-25 15:32:58 +00:00
|
|
|
|
2012-03-21 05:33:37 +00:00
|
|
|
Example Script
|
|
|
|
--------------
|
|
|
|
|
2016-06-12 01:20:13 +00:00
|
|
|
.. literalinclude:: __/__/__/release/scripts/templates_py/bmesh_simple.py
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
Standalone Module
|
|
|
|
^^^^^^^^^^^^^^^^^
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
The BMesh module is written to be standalone except for :mod:`mathutils`
|
2012-03-13 06:22:43 +00:00
|
|
|
which is used for vertex locations and normals.
|
|
|
|
The only other exception to this are when converting mesh data to and from :class:`bpy.types.Mesh`.
|
|
|
|
|
|
|
|
|
|
|
|
Mesh Access
|
|
|
|
-----------
|
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
There are two ways to access BMesh data, you can create a new BMesh by converting a mesh from
|
|
|
|
:class:`bpy.types.BlendData.meshes` or by accessing the current Edit-Mode mesh.
|
|
|
|
See: :class:`bmesh.types.BMesh.from_mesh` and :mod:`bmesh.from_edit_mesh` respectively.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
When explicitly converting from mesh data Python **owns** the data, that means that
|
|
|
|
the mesh only exists while Python holds a reference to it.
|
|
|
|
The script is responsible for putting it back into a mesh data-block when the edits are done.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
Note that unlike :mod:`bpy`, a BMesh does not necessarily correspond to data in the currently open blend-file,
|
2012-03-13 06:22:43 +00:00
|
|
|
a BMesh can be created, edited and freed without the user ever seeing or having access to it.
|
2020-06-23 13:08:49 +00:00
|
|
|
Unlike Edit-Mode, the BMesh module can use multiple BMesh instances at once.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
Take care when dealing with multiple BMesh instances since the mesh data can use a lot of memory.
|
|
|
|
While a mesh that the Python script owns will be freed when the script holds no references to it,
|
|
|
|
it's good practice to call :class:`bmesh.types.BMesh.free` which will remove all the mesh data immediately
|
|
|
|
and disable further access.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2012-03-29 13:44:30 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
Edit-Mode Tessellation
|
|
|
|
^^^^^^^^^^^^^^^^^^^^^^
|
2012-03-29 13:44:30 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
When writing scripts that operate on Edit-Mode data you will normally want to re-calculate the tessellation after
|
|
|
|
running the script, this needs to be called explicitly.
|
|
|
|
The BMesh itself does not store the triangulated faces, instead they are stored in the :class:`bpy.types.Mesh`,
|
2018-09-06 12:28:14 +00:00
|
|
|
to refresh tessellation triangles call :class:`bpy.types.Mesh.calc_loop_triangles`.
|
2012-03-29 13:44:30 +00:00
|
|
|
|
|
|
|
|
2012-03-21 05:33:37 +00:00
|
|
|
CustomData Access
|
|
|
|
-----------------
|
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
BMesh has a unified way to access mesh attributes such as UVs, vertex colors, shape keys, edge crease, etc.
|
|
|
|
This works by having a **layers** property on BMesh data sequences to access the custom data layers
|
|
|
|
which can then be used to access the actual data on each vert, edge, face or loop.
|
2012-03-21 05:33:37 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
Here are some examples:
|
2012-03-21 05:33:37 +00:00
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
uv_lay = bm.loops.layers.uv.active
|
|
|
|
|
|
|
|
for face in bm.faces:
|
2012-05-22 15:19:19 +00:00
|
|
|
for loop in face.loops:
|
|
|
|
uv = loop[uv_lay].uv
|
2012-05-22 18:14:34 +00:00
|
|
|
print("Loop UV: %f, %f" % uv[:])
|
|
|
|
vert = loop.vert
|
|
|
|
print("Loop Vert: (%f,%f,%f)" % vert.co[:])
|
2012-03-21 05:33:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
shape_lay = bm.verts.layers.shape["Key.001"]
|
|
|
|
|
|
|
|
for vert in bm.verts:
|
2012-04-22 23:51:50 +00:00
|
|
|
shape = vert[shape_lay]
|
|
|
|
print("Vert Shape: %f, %f, %f" % (shape.x, shape.y, shape.z))
|
2012-03-21 05:33:37 +00:00
|
|
|
|
|
|
|
|
2012-03-27 10:30:10 +00:00
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
# in this example the active vertex group index is used,
|
|
|
|
# this is stored in the object, not the BMesh
|
|
|
|
group_index = obj.vertex_groups.active_index
|
|
|
|
|
|
|
|
# only ever one deform weight layer
|
|
|
|
dvert_lay = bm.verts.layers.deform.active
|
|
|
|
|
|
|
|
for vert in bm.verts:
|
|
|
|
dvert = vert[dvert_lay]
|
2012-04-22 23:51:50 +00:00
|
|
|
|
2012-03-27 10:30:10 +00:00
|
|
|
if group_index in dvert:
|
|
|
|
print("Weight %f" % dvert[group_index])
|
|
|
|
else:
|
|
|
|
print("Setting Weight")
|
|
|
|
dvert[group_index] = 0.5
|
|
|
|
|
|
|
|
|
2012-03-13 06:22:43 +00:00
|
|
|
Keeping a Correct State
|
|
|
|
-----------------------
|
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
When modeling in Blender there are certain assumptions made about the state of the mesh:
|
2012-03-13 06:22:43 +00:00
|
|
|
|
2020-06-23 13:08:49 +00:00
|
|
|
- Hidden geometry isn't selected.
|
|
|
|
- When an edge is selected, its vertices are selected too.
|
|
|
|
- When a face is selected, its edges and vertices are selected.
|
|
|
|
- Duplicate edges / faces don't exist.
|
|
|
|
- Faces have at least three vertices.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
To give developers flexibility these conventions are not enforced,
|
2020-06-23 13:08:49 +00:00
|
|
|
yet tools must leave the mesh in a valid state or else other tools may behave incorrectly.
|
2012-03-13 06:22:43 +00:00
|
|
|
Any errors that arise from not following these conventions is considered a bug in the script,
|
2020-06-23 13:08:49 +00:00
|
|
|
not a bug in Blender.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
Selection / Flushing
|
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
|
|
As mentioned above, it is possible to create an invalid selection state
|
2020-06-23 13:08:49 +00:00
|
|
|
(by selecting a state and then deselecting one of its vertices for example),
|
|
|
|
mostly the best way to solve this is to flush the selection
|
|
|
|
after performing a series of edits. This validates the selection state.
|
2012-03-13 06:22:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
Module Functions
|
|
|
|
----------------
|