При работе оператора от назначенной кнопки почему-то не происходит смена текущего объекта, сиречь 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()
При этом код, изменяющий активность/выбранность объекта не работает:
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()
Комментариев нет:
Отправить комментарий