Rotation of meshes in PyTorch I am doing some project on object reconstruction and I need to rotate an object in PyTorch during the training to make sure I am augmenting the data properly. My data consists of points and it's normals. My question is, how should I (or should I train them at all) rotate the normals of my mesh. Note that this rotation also needs to keep the object inside the unit cube, where it was before the transformation.
My question is, how should I (...) rotate normals of my mesh.


Normals are rotated the same way as the rest of your mesh/point cloud. But make sure that you use a "pure rotation matrix" for this (no scaling, no translation). Since rotations preserve lengths, you do not need to renormalize your normals (usually - floating-point errors might accumulate).

This sentence of you


  Note that this rotation also needs to keep object in unit cube, where it was before running this code.


lets me guess, that you are actually asking how to rotate an object and its normals and not just the normals. In python, you can use the packages SciPy and NumPy for that.

The Rotation package (documentation) of SciPy helps you to generate an arbitrary rotation matrix. Then you can use NumPys matmul function to rotate your points and normals.

Here is a short example script that rotates a single point 20 degrees around the z axis:

from scipy.spatial.transform import Rotation as Rot
import numpy as np

p = np.array([1, 1, 0]).transpose()
rot_mat = Rot.from_euler(seq="z", angles=20, degrees=True).as_matrix()

p_r = np.matmul(rot_mat, p)

print(p)
print(p_r)
print(np.linalg.norm(p))
print(np.linalg.norm(p_r))


output:

[1 1 0]
[0.59767248 1.28171276 0.        ]
1.4142135623730951
1.414213562373095



  Info: Depending on your SciPy version you might need to replace as_matrix with as_dcm


As you can see, apart from some minor floating-point error, the length (last 2 outputs) did not change. Furthermore, I chose the example point, so that it gets outside the unit cube. To address this problem, you need to find the maximum absolute value inside the transformed data. You can use amax and amin to get the maximum and minimum value (see also here) if you put all your coordinates into one large 2d array (a matrix). Then compare the absolute values of the amax and amin results and pick the larger one. Divide all your coordinates (not the normals!) by this value, to scale your model back into the unit cube. Alternatively, you can create a uniform scaling matrix

$$
\begin{bmatrix}
s&amp;0&amp;0\\
0&amp;s&amp;0\\
0&amp;0&amp;s
\end{bmatrix}
$$

with $s$ being the reciprocal of the maximum absolute value. Multiply this matrix with all points.

To sum it up:


calculate the rotation matrix with SciPy
Multiply the rotation matrix with all points and normals
find the maximum absolute value in the rotated data
scale your coordinates with the found maximum value


Remark: If you put your points and normals into 2 matrices, you can apply the rotations and scaling matrices without a loop, which makes it much faster.