I watched this video from Keenan Crane this morning. The discrete Gauss-Bonnet theorem impresses me so much and I think I can illustrate it in Blender scripting.

The discrete Gauss-Bonnet theorem(quoted from here):

Consider a (connected, orientable) simplicial surface \( \mathbf{K} \) with finitely many vertices \( \mathbf{V} \), edges \( \mathbf{E} \) and faces \( \mathbf{F} \). A discrete analog of the Gauss-Bonnet theorem holds for simplicial surfaces, namely

where \( \chi = |\mathbf{V}| - |\mathbf{E}| + |\mathbf{F}|\) is the Euler characteristic of the surface, and \( d(v) \) is the angle defect:

where \( \mathbf{F}_v \) is the faces containing \( v \) and \( \angle_f(v) \) is the interior angle of the face \( f \) at vertex \( v \).

The implementation is straightforward from the above theorem statements. I put my source code on the gist. You can run it as a Blender operator. And remember to check Blender’s info view for results.

There is one thing worthing noting. In my first try of implementing this operator, I traverse link_edges for each vertex to calculate interior angles, expecting that the adjacent edges are stored in link_edges sequence.

However this does not work as expected. The edges in link_edges are not arranged in any specific order(neither clock-wise nor counter-clock-wise). Therefore I can not make any assumption on it.

Then I try another approach: I traverse faces in link_faces for each vertex, and find the adjacent edges from the face. This approach works for me.

I kept both implementations(AngleDefects and AngleDefects2) in my source code, so you can play around with them.