คลายรูปหลายเหลี่ยมสี่เหลี่ยมด้วย Python: ทั้ง 3 แกน

Sep 15 2020

ฉันมีรูปหลายเหลี่ยมสี่เหลี่ยมที่หมุนได้ และฉันต้องการ 'คลายการหมุน' เพื่อให้แกนปกติของมันตรงกับแกนโลก

ฉันสามารถคลายการหมุนบนแกน Z ได้โดยใช้ใบหน้าปกติและความแตกต่างของการหมุน (ฉันไม่สนใจเกี่ยวกับการแปลในตอนนี้):

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

แต่สำหรับความรักของพระเจ้าฉันคิดไม่ออกว่าจะเพิ่มการหมุนใบหน้า X และ Y ในส่วนผสมได้อย่างไร

ผลลัพธ์ที่ต้องการ:

คำตอบ

9 batFINGER Sep 15 2020 at 17:01

ใช้ขอบ

โมดูล bmesh มีวิธีการบางอย่างสำหรับใบหน้าในการคำนวณเวกเตอร์แทนเจนต์ของใบหน้าตามขอบ ตัวอย่างเช่นจะใช้เวกเตอร์แทนเจนต์ที่สร้างจากสองขอบที่ยาวที่สุดที่ไม่เชื่อมต่อกัน

การใช้ใบหน้าปกติแทนเจนต์ของใบหน้าและผลคูณข้ามของทั้งสองสามารถสร้างเมทริกซ์การหมุนจากเวกเตอร์มุมฉากทั้งสามได้

แกนเป็นคอลัมน์ของเมทริกซ์ดังนั้นเมทริกซ์การหมุนที่มีแกนเวกเตอร์หน่วยx, y, and zอาจเป็นได้

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

ถ้าคุณจำได้จากพีชคณิตเชิงเส้นการทรานสโพสของเมทริกซ์มุมฉากก็เป็นผกผันเช่นกัน

สคริปต์ทดสอบจัดแนวหน้าศูนย์ตามเมทริกซ์ที่สร้างไว้ด้านบน

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)