Создайте объект поверх грани, выровненный с и ближайший к 3d-курсору (Blender) - PullRequest
0 голосов
/ 26 апреля 2020

Цель следующего кода - создать цилиндр над 3d-курсором и повернуть цилиндр так, чтобы он выровнялся с ближайшей к нему гранью выделенного объекта.

import bpy
from bpy_extras.object_utils import AddObjectHelper
from bpy.types import Operator
from math import radians
from mathutils import Matrix, Vector, Euler

###Aux
def rotate_to_vec(thevector):
    from bpy import context
    vec = thevector
    obj = context.object
    # object axis to align with vector vec
    axis = Vector((0, 0, 1.0))

    # rotation difference
    q = axis.rotation_difference(vec)
    # or
    # track quaternion
    #q = vec.to_track_quat('X', 'Z')

    loc, rot, scale = obj.matrix_world.decompose()

    mat_scale = Matrix()
    for i in range(3):
        mat_scale[i][i] = scale[i]

    obj.matrix_world = (
        Matrix.Translation(loc) * 
        q.to_matrix().to_4x4() * 
        mat_scale)

###Methods    
def CilinderOnFaceGQPFun(self, context):
    #Aliases
    obj = bpy.context.object
    name = obj.name
    me = obj.data
    test_angle = radians(85) 

    ##Select face nearest to cursor
    cur = bpy.context.scene.cursor_location
    vec = obj.closest_point_on_mesh( cur )[2]
    faceIdx = obj.closest_point_on_mesh( cur )[-1]
    if faceIdx != -1:
        #obj.data.polygons[ faceIdx ].select = True
        print (vec)
    else: print("face not found")

    loca = bpy.context.scene.cursor_location

    bpy.ops.mesh.primitive_cylinder_add(radius=3, depth=10, location=loca)
    rotate_to_vec(vec)

    #Select the main object again
    bpy.ops.object.select_all(action='DESELECT');
    bpy.data.objects[name].select = True
    bpy.context.scene.objects.active = bpy.data.objects[name]


class CilinderOnFaceGQP(Operator, AddObjectHelper):
    """Create a new Mesh Object"""
    bl_idname = "object.cilinder_on_face_gqp"
    bl_label = "Ubicar Cilindro en Cara"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):

        CilinderOnFaceGQPFun(self, context)

        return {'FINISHED'}   

###Register      
def register():
    bpy.utils.register_class(CilinderOnFaceGQP)


def unregister():
    bpy.utils.unregister_class(CilinderOnFaceGQP)

if __name__ == "__main__":
    register()  

Работает с объект выровнен относительно начала координат, но как только вы захватите или поверните его, ориентация вновь созданных цилиндров будет неправильной

Пожалуйста, спросите, нужна ли вам дополнительная информация для решения этой проблемы

...