Determining the angle between two adjacent mesh edges is necessary, for example, when searching for elements on the model that are too sharp, or, conversely, not sharp enough.
To calculate the angle between two mesh edges adjacent to one point, it is most convenient to use the bmesh structure.
Create a bmesh object and load the geometry of the current active scene mesh into it. Bring the indexing of vertices and edges into accordance with the indexing of the original mesh.
1 2 3 4 5 6 7 |
import bmesh bm = bmesh.new() bm.from_mesh(bpy.context.object.data) bm.verts.ensure_lookup_table() bm.edges.ensure_lookup_table() |
Let’s take a point with index 0. Two edges are adjacent to it, between which we want to calculate the angle.
1 |
vert = bm.verts[0] |
We can get both edges adjacent to a point using its link_edges property:
1 2 |
edge0 = vert.link_edges[0] edge1 = vert.link_edges[1] |
Now starting from the edges, we can get their common vertex:
1 |
vert0 = edge0.verts[0] if edge0.verts[0] in edge1.verts else edge0.verts[1] |
and the two remaining vertices:
1 2 |
vert1 = edge0.other_vert(vert0) vert2 = edge1.other_vert(vert0) |
Now, using these three points, we can construct two vectors corresponding to two mesh edges:
1 2 |
vec0 = vert0.co - vert1.co vec1 = vert0.co - vert2.co |
To calculate the angle between two vectors, we can get their dot product, or we can use the angle() function from the mathutils module, which does the same thing.
1 |
angle = vec0.angle(vec1) |
There are actually two angles between two vectors. Most often, when doing calculations, we need the inner (smaller) of them. The angle() function calculates the angle between vectors in a right-handed coordinate system i.e. clockwise. Accordingly, we do not know exactly what angle we will get as a result. However, we can simply compare the angle with 180 degrees, and if it is greater, then we have found an external (larger) angle. To get the internal one, we need to subtract the resulting value by 360 degrees.
Note that the angle() function returns the result in radians. To operate with degrees, we need to remember to make transformations.
1 2 3 |
from math import radians, degrees angle = angle if angle < radians(180) else (radians(360) - angle) |
As a result, we will get the angle we need:
1 2 3 |
print(degrees(angle)) # 116.832 |