Python API: add loop triangles access, remove tessfaces.
Loop triangles are tessellated triangles create from polygons, for renderers or exporters that need to match Blender's polygon tesselation exactly. These are a read-only runtime cache. Tessfaces are a legacy data structure from before Blender supported n-gons, and were already mostly removed from the C code. Details on porting code to loop triangles is in the release notes. Differential Revision: https://developer.blender.org/D3539
This commit is contained in:
@@ -83,7 +83,7 @@ When writing scripts that operate on editmode data you will normally want to re-
|
||||
running the script, this needs to be called explicitly.
|
||||
|
||||
The BMesh its self does not store the triangulated faces, they are stored in the :class:`bpy.types.Mesh`,
|
||||
to refresh tessellation faces call :class:`bpy.types.Mesh.calc_tessface`.
|
||||
to refresh tessellation triangles call :class:`bpy.types.Mesh.calc_loop_triangles`.
|
||||
|
||||
|
||||
CustomData Access
|
||||
|
@@ -164,26 +164,26 @@ for list removal, but these are slower.
|
||||
Sometimes its faster (but more memory hungry) to just rebuild the list.
|
||||
|
||||
|
||||
Say you want to remove all triangular faces in a list.
|
||||
Say you want to remove all triangular polygons in a list.
|
||||
|
||||
Rather than...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
faces = mesh.tessfaces[:] # make a list copy of the meshes faces
|
||||
f_idx = len(faces) # Loop backwards
|
||||
while f_idx: # while the value is not 0
|
||||
f_idx -= 1
|
||||
polygons = mesh.polygons[:] # make a list copy of the meshes polygons
|
||||
p_idx = len(polygons) # Loop backwards
|
||||
while p_idx: # while the value is not 0
|
||||
p_idx -= 1
|
||||
|
||||
if len(faces[f_idx].vertices) == 3:
|
||||
faces.pop(f_idx) # remove the triangle
|
||||
if len(polygons[p_idx].vertices) == 3:
|
||||
polygons.pop(p_idx) # remove the triangle
|
||||
|
||||
|
||||
It's faster to build a new list with list comprehension.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
faces = [f for f in mesh.tessfaces if len(f.vertices) != 3]
|
||||
polygons = [p for p in mesh.polygons if len(p.vertices) != 3]
|
||||
|
||||
|
||||
Adding List Items
|
||||
|
@@ -173,25 +173,25 @@ In this situation you can...
|
||||
|
||||
.. _info_gotcha_mesh_faces:
|
||||
|
||||
N-Gons and Tessellation Faces
|
||||
=============================
|
||||
N-Gons and Tessellation
|
||||
=======================
|
||||
|
||||
Since 2.63 NGons are supported, this adds some complexity
|
||||
since in some cases you need to access triangles/quads still (some exporters for example).
|
||||
since in some cases you need to access triangles still (some exporters for example).
|
||||
|
||||
There are now 3 ways to access faces:
|
||||
|
||||
- :class:`bpy.types.MeshPolygon` -
|
||||
this is the data structure which now stores faces in object mode
|
||||
(access as ``mesh.polygons`` rather than ``mesh.faces``).
|
||||
- :class:`bpy.types.MeshTessFace` -
|
||||
the result of triangulating (tessellated) polygons,
|
||||
the main method of face access in 2.62 or older (access as ``mesh.tessfaces``).
|
||||
- :class:`bpy.types.MeshLoopTriangle` -
|
||||
the result of tessellating polygons into triangles
|
||||
(access as ``mesh.loop_triangles``).
|
||||
- :class:`bmesh.types.BMFace` -
|
||||
the polygons as used in editmode.
|
||||
|
||||
For the purpose of the following documentation,
|
||||
these will be referred to as polygons, tessfaces and bmesh-faces respectively.
|
||||
these will be referred to as polygons, loop triangles and bmesh-faces respectively.
|
||||
|
||||
5+ sided faces will be referred to as ``ngons``.
|
||||
|
||||
@@ -234,13 +234,8 @@ All 3 datatypes can be used for face creation.
|
||||
|
||||
- polygons are the most efficient way to create faces but the data structure is _very_ rigid and inflexible,
|
||||
you must have all your vertes and faces ready and create them all at once.
|
||||
This is further complicated by the fact that each polygon does not store its own verts (as with tessfaces),
|
||||
This is further complicated by the fact that each polygon does not store its own verts,
|
||||
rather they reference an index and size in :class:`bpy.types.Mesh.loops` which are a fixed array too.
|
||||
- tessfaces ideally should not be used for creating faces since they are really only tessellation cache of polygons,
|
||||
however for scripts upgrading from 2.62 this is by far the most straightforward option.
|
||||
This works by creating tessfaces and when finished -
|
||||
they can be converted into polygons by calling :class:`bpy.types.Mesh.update`.
|
||||
The obvious limitation is ngons can't be created this way.
|
||||
- bmesh-faces are most likely the easiest way for new scripts to create faces,
|
||||
since faces can be added one by one and the api has features intended for mesh manipulation.
|
||||
While :class:`bmesh.types.BMesh` uses more memory it can be managed by only operating on one mesh at a time.
|
||||
@@ -271,30 +266,6 @@ the choice mostly depends on whether the target format supports ngons or not.
|
||||
since using bmesh gives some overhead because its not the native storage format in object mode.
|
||||
|
||||
|
||||
Upgrading Importers from 2.62
|
||||
-----------------------------
|
||||
|
||||
Importers can be upgraded to work with only minor changes.
|
||||
|
||||
The main change to be made is used the tessellation versions of each attribute.
|
||||
|
||||
- mesh.faces --> :class:`bpy.types.Mesh.tessfaces`
|
||||
- mesh.uv_textures --> :class:`bpy.types.Mesh.tessface_uv_textures`
|
||||
- mesh.vertex_colors --> :class:`bpy.types.Mesh.tessface_vertex_colors`
|
||||
|
||||
Once the data is created call :class:`bpy.types.Mesh.update` to convert the tessfaces into polygons.
|
||||
|
||||
|
||||
Upgrading Exporters from 2.62
|
||||
-----------------------------
|
||||
|
||||
For exporters the most direct way to upgrade is to use tessfaces as with importing
|
||||
however its important to know that tessfaces may **not** exist for a mesh,
|
||||
the array will be empty as if there are no faces.
|
||||
|
||||
So before accessing tessface data call: :class:`bpy.types.Mesh.update` ``(calc_tessface=True)``.
|
||||
|
||||
|
||||
EditBones, PoseBones, Bone... Bones
|
||||
===================================
|
||||
|
||||
|
Reference in New Issue
Block a user