Annuler la rotation d'un polygone carré avec Python: les 3 axes

Sep 15 2020

J'ai un polygone carré tourné. Et je veux le «défaire» pour que ses axes normaux correspondent aux axes du monde.

Je suis capable de le faire pivoter sur l'axe Z en utilisant la normale de la face et la différence de rotation (je ne me soucie pas de la translation à ce stade):

quaternion = Vector((0,0,1)).rotation_difference(face_normal)
rotation = ( +quaternion ).to_matrix().inverted()
obj.matrix_world = rotation.to_4x4()

Mais pour l'amour de Dieu, je ne peux pas comprendre comment ajouter également la rotation des faces X et Y au mélange.

Résultat désiré:

Réponses

9 batFINGER Sep 15 2020 at 17:01

Utilisez les bords.

Le module bmesh a quelques méthodes pour les faces pour calculer le vecteur tangent de la face en fonction de ses arêtes. Par exemple, sake utilisera le vecteur tangent créé à partir des deux plus longues arêtes non connectées.

En utilisant la normale de face, la tangente de face et le produit croisé des deux peuvent créer une matrice de rotation à partir des trois vecteurs orthogonaux.

Les axes sont les colonnes d'une matrice, donc une matrice de rotation avec des axes vectoriels unitaires x, y, and zpourrait être

Matrix((x, y, z)).transposed()

si vous vous rappelez de l'algèbre linéaire, la transposée d'une matrice orthogonale est aussi son inverse.

Script de test, aligne la face zéro en fonction de la matrice créée comme ci-dessus.

import bpy
import bmesh
from mathutils import Matrix, Quaternion

ob = bpy.context.object
me = ob.data
bm = bmesh.from_edit_mesh(me)
face = bm.faces[0]

 
n = face.normal
t = face.calc_tangent_edge_pair().normalized()
c = face.calc_center_median()

M = (
    Matrix.Translation(c) @ 
    Matrix((t.cross(n).normalized(), t, n)).to_4x4() @
    Matrix.Translation(-c)
    )

bmesh.ops.transform(
    bm,
    matrix=M,
    verts=bm.verts,
    )
bmesh.update_edit_mesh(me)