воскресенье, 6 ноября 2016 г.

Как я и думал.

    При работе оператора от назначенной кнопки почему-то не происходит смена текущего объекта, сиречь bpy.context.object. Поэтому, при работе все модификаторы вешаются не на клоны объекта, а на  сам объект.


При этом код, изменяющий активность/выбранность объекта не работает:
        newOb.select = True
        bpy.context.scene.objects.active = bpy.data.objects[newOb.name]
        print(bpy.context.object.name, bpy.context.scene.objects.active.name)

Возвращает в консоль:
       Sphere SphereExplode1                                                

Естественно, все операторы работают именно с первым объектом, а надо-то чтобы со вторым. При этом, при запуске оператора с помощью кнопки Run Script оператор работает нормально. Пробовал сделать через вызов оператора с помощью сохраненного скрипта, та же петрушка, нет смены активного объекта. Надо думать. Как все-таки удобно сделано в BGE, данные объекта упакованы сразу с методами его обработки. Немного измененный вариант скрипта:

import bpy

def main(diff = 4, start_Fr = 1, end_Fr = 24):
   
    print('<<<<<<<>>>>>>>')
   
    object = bpy.context.object
   
    name = object.name
   
    listName = []
   
    index = 0
   
    for frame in range(start_Fr, end_Fr, diff):
        bpy.context.scene.frame_current = 1
        object.select = True
        bpy.context.scene.objects.active = object
        bpy.ops.object.duplicate()
        bpy.ops.object.select_all(action = 'DESELECT')
        newOb = bpy.context.scene.objects.active
        newOb.name = name + 'Explode' + str(frame)      
        listName.append((newOb.name, frame, index))
        index = index + 1
        newOb.location[1] = index * newOb.dimensions[1]
        #part_S = newOb.particle_systems[-1]
        #print(newOb.name, newOb.particle_systems)
        newOb.select = True
       
        bpy.context.scene.objects.active = bpy.data.objects[newOb.name]
        print(bpy.context.object.name, bpy.context.scene.objects.active.name)
       
        bpy.ops.object.modifier_add(type = 'PARTICLE_SYSTEM')
        part_S = newOb.particle_systems['ParticleSystem']
        part_S.settings.frame_start = start_Fr
        part_S.settings.frame_end = 1
        part_S.settings.count = 32
        part_S.settings.lifetime = 50
        part_S.settings.object_align_factor[2] = 11
        part_S.settings.factor_random = 12
        part_S.settings.integrator = 'EULER'
        bpy.ops.object.modifier_add(type = 'EXPLODE')
        newOb.modifiers['Explode'].show_dead = False
        bpy.context.scene.frame_current = frame
        bpy.ops.object.modifier_apply(modifier = 'Explode')
        bpy.ops.object.particle_system_remove()
        bpy.ops.object.modifier_add(type = 'SOLIDIFY')
        newOb.modifiers['Solidify'].thickness = 0.1
        bpy.ops.object.modifier_apply(modifier = 'Solidify')
        #print(newOb.modifiers)
        bpy.ops.object.select_all(action = 'DESELECT')
    print(listName)
    # Здесь будем добавлять клонов как ключи формы, причем самому первому клону,
    # потому что нельзя добавит объект в ключи другому объекту, если у них
    # разное число вершин.
   
    for name, frame, index in listName:
        # пропускаем первого клона, на него будем писать ключи формы
        if index == 0:
            continue
        else:
            # понятно, выковыриваем клон(не первый) по имени, он пойдет в ключ формы
            currObj = bpy.context.scene.objects[name]
            # выбираем его
            currObj.select = True
            # получаем первого клона
            explObject = bpy.context.scene.objects[listName[0][0]]
            # выбираем его и делаем его активным
            explObject.select = True
            bpy.context.scene.objects.active = explObject
            # пишем текущий клон в ключ формы первого клона
            bpy.ops.object.join_shapes()
            # снимем выделение со всех объектов сцены
            bpy.ops.object.select_all(action = 'DESELECT')
            # снова выбираем текущего клона и в этот раз делаем его активным
            bpy.context.scene.objects.active = currObj
            currObj.select = True
            # удаляем текущий клон      
            bpy.ops.object.delete()
           
    # Здесь будем анимировать ключи формы
         
    # снимаем выделение со всех объектов, на всякий пожарный  
    bpy.ops.object.select_all(action = 'DESELECT')
    # выделям перый и теперь уже единственный клон
    objExpl = bpy.context.scene.objects[listName[0][0]]
    bpy.context.scene.objects.active = objExpl
    objExpl.select = True
    # получаем его список ключей форм
    shapeKeys = objExpl.data.shape_keys

    for name, frame, index in listName:
        # достаем ключ формы по имени, на всякий случай проверяя, есть ли такой
        if name in shapeKeys.key_blocks:
            # текущий ключ формы
            currBlock = shapeKeys.key_blocks[name]
            # генерируем список из кортежей "значение - кадр"
            frameList = [(0.0, frame-diff), (1.0, frame), (0.0, frame+diff)]
            # И по этому списку задаем ключи анимации ключам формы
            for J in frameList:
#                print(J) #debug
                currBlock.value = J[0]
                currBlock.keyframe_insert("value", frame = J[1])
#            print(currBlock.name) #debug
         
class explodeToShape(bpy.types.Operator):
    """Создает дубликат объекта"""
    bl_idname = "object.explode_to_shape"
    bl_label = "Explode To Shape"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        main()
        return {'FINISHED'}
   
class myPanel(bpy.types.Panel):
    bl_label = 'ExplodeIt'
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = 'data'
   
    def draw(self, context):
        layout = self.layout
        layout.operator("object.explode_to_shape", text = 'ExplodeToShape')

def register():
    bpy.utils.register_class(explodeToShape)
    bpy.utils.register_class(myPanel)
   
def unregister():
    bpy.utils.unregister_class(explodeToShape)
    bpy.utils.unregister_class(myPanel)

             
if __name__ == "__main__":
    register()

    # test call
    #bpy.ops.object.explode_to_shape()

Комментариев нет:

Отправить комментарий