Calculate rotation angle of each uv triangle

Hello guys,

I try to create a javascript/python function that works like ‘Preserve UVs’ in 3DS Max. So the goal is to be able to modify the position of vertices without breaking/stretching/… the uv map. The uv map should adapt to the changes that are made to vertices. This video shows is clearly: https://www.youtube.com/watch?v=NUuxXsCPzWk

The first step is to know how each triangle (yes, the mesh is triangulated and doesn’t use quads since it gets converted to gltf/glb) is rotated on the uv map. I am able to calculate the rotation angle like this:

uv_1 = uvs[index_1]
uv_2 = uvs[index_2]
vector = { x: uv_2.x - uv_1.x, y: uv_2.y - uv_1.y }
radians = atan2(vector.x, vector.y)

Unfortunately this doesn’t work for all triangles since the indices are in different orders. If we follow this pattern for our indices ‘0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6, …’ we need to change the indices likes this in our function:

index_1 = index_1
index_2 = index_2 if faceIndex % 2 else index_2+1
uv_1 = uvs[index_1]
uv_2 = uvs[index_2]
vector = { x: uv_2.x - uv_1.x, y: uv_2.y - uv_1.y }
radians = atan2(vector.x, vector.y)

Obviously this is not working correctly. The gltf exporter triangulates the mesh the same way as using the Triangulate Modifier with Quad Method = Fixed. This is important to know to determine the correct indices.

That are all my insights so far. I would really appreciate if you could guide me to calculate the rotation angle of each uv triangle. The formula should be correct but how am I able to know which indices I have to use?

Isn’t this what UV → Texture Lock is for ?