Хвастать пока нечем. Пока делал GUI для оператора взрыва объекта, в общем ниже картинка:
Целый шарик - это объект, для которого готовится "взрывчатый клон". Сам клон виден в виде кусочков чуть правее, кадр анимации отличается от стартового, поэтому его уже разбросало. Видно настройки оператора в Т-панели.
До кучи можно посмотреть какой на данный момент код:
bl_info = {
"name" : "ExplodeToShape",
"author" : "denis8424",
"category" : "Game Engine",
"version" : (0, 5),
}
import bpy
def main(animationProps, solidifyProps, dead_Explode, particleProps):
########################
# VAR
########################
stepA = animationProps[0]
start_Fr = animationProps[1]
end_Fr = animationProps[2]
useSolidify = solidifyProps[0]
thickness = solidifyProps[1]
count = particleProps[0]
lifetime = particleProps[1]
factor_random = particleProps[2]
factor_random = particleProps[3]
object_align_factor_X = particleProps[4]
object_align_factor_Y = particleProps[5]
object_align_factor_Z = particleProps[6]
print('<<<<<<<>>>>>>>')
object = bpy.context.object
name = object.name
listName = []
index = 0
for frame in range(start_Fr, end_Fr, stepA):
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]
bpy.ops.object.modifier_add(type = 'PARTICLE_SYSTEM')
#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)
part_S = newOb.particle_systems['ParticleSystem']
part_S.settings.frame_start = start_Fr
part_S.settings.frame_end = start_Fr
part_S.settings.count = count
part_S.settings.lifetime = lifetime
part_S.settings.object_align_factor[0] = object_align_factor_X
part_S.settings.object_align_factor[1] = object_align_factor_Y
part_S.settings.object_align_factor[2] = object_align_factor_Z
part_S.settings.factor_random = factor_random
part_S.settings.normal_factor = factor_random
part_S.settings.integrator = 'EULER'
bpy.ops.object.modifier_add(type = 'EXPLODE')
newOb.modifiers['Explode'].show_dead = dead_Explode
bpy.context.scene.frame_current = frame
bpy.ops.object.modifier_apply(modifier = 'Explode')
bpy.ops.object.particle_system_remove()
if useSolidify == True:
bpy.ops.object.modifier_add(type = 'SOLIDIFY')
newOb.modifiers['Solidify'].thickness = thickness
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:
#print(name)
# пропускаем первого клона, на него будем писать ключи формы
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-stepA), (1.0, frame), (0.0, frame+stepA)]
# И по этому списку задаем ключи анимации ключам формы
for J in frameList:
# print(J) #debug
currBlock.value = J[0]
currBlock.keyframe_insert("value", frame = J[1])
bpy.context.scene.frame_current = 1
class ExplodeOperator(bpy.types.Operator):
"""Explode object"""
bl_idname = "object.explode_operator"
bl_label = "Explode Object Operator"
bl_options = {'REGISTER', 'UNDO'}
stepA = bpy.props.IntProperty(
name = "stepA",
default = 1,
min = 1,
max = 8,
step = 1,
description = "differential"
)
start_Fr = bpy.props.IntProperty(
name = "start frame",
default = 1,
min = 1,
max = 255,
step = 1,
description = "start frame"
)
end_Fr = bpy.props.IntProperty(
name = "end_frame",
default = 8,
min = 1,
max = 255,
step = 1,
description = "end frame"
)
thickness_Solidify = bpy.props.FloatProperty(
name = "thickness_Solidify",
default = 0.05,
min = 0.01,
max = 1.0,
step = 1,
description = "Solidify thickness"
)
use_Solidify = bpy.props.BoolProperty(
name = 'use_Solidify',
default = False,
description = 'Solidify usy or not'
)
dead_Explode = bpy.props.BoolProperty(
name = 'Explode Dead',
default = False,
description = 'dead_Explode'
)
count = bpy.props.IntProperty(
name = "count",
default = 32,
min = 1,
max = 255,
step = 1,
description = "Particle Count"
)
lifetime = bpy.props.IntProperty(
name = "lifetime",
default = 50,
min = 1,
max = 255,
step = 1,
description = "Particle lifetime"
)
factor_random = bpy.props.FloatProperty(
name = "factor_random",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle random factor"
)
factor_normal = bpy.props.FloatProperty(
name = "factor_normal",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle normal factor"
)
object_align_factor_X = bpy.props.FloatProperty(
name = "object_align_factor_X",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
object_align_factor_Y = bpy.props.FloatProperty(
name = "object_align_factor_Y",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
object_align_factor_Z = bpy.props.FloatProperty(
name = "object_align_factor_Z",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
animationProps = [
self.stepA,
self.start_Fr,
self.end_Fr
]
solidifyProps = [
self.use_Solidify,
self.thickness_Solidify
]
particleProps = [
self.count,
self.lifetime,
self.factor_random,
self.factor_normal,
self.object_align_factor_X,
self.object_align_factor_Y,
self.object_align_factor_Z
]
main(
animationProps,
solidifyProps,
self.dead_Explode,
particleProps
)
return {'FINISHED'}
def draw(self, context):
layout = self.layout
layout.label(text = 'Animation:')
box = layout.box()
box.prop(self, 'stepA')
row = box.row(align = True)
row.prop(self, 'start_Fr')
row.prop(self, 'end_Fr')
layout.label(text = 'Solidify Modifier:')
box = layout.box()
row = box.row(align = True)
#row.label(text = 'Solidify:')
row.prop(self, 'use_Solidify')
if self.use_Solidify == True:
box.prop(self, 'thickness_Solidify')
# layout.label(text = 'Explode Modifier:')
# box = layout.box()
# box.prop(self, 'dead_Explode')
layout.label(text = 'Particle System:')
box = layout.box()
box.prop(self, 'count')
box.prop(self, 'lifetime')
box.prop(self, 'factor_random')
box.prop(self, 'factor_normal')
col = box.column(align = True)
col.prop(self, 'object_align_factor_X')
col.prop(self, 'object_align_factor_Y')
col.prop(self, 'object_align_factor_Z')
def add_object_menu(self, context):
self.layout.separator()
self.layout.operator(
ExplodeOperator.bl_idname,
text = ExplodeOperator.__doc__)
self.layout.label(text = 'EXPLODEEEEE!!!!')
self.layout.separator()
def register():
bpy.utils.register_class(ExplodeOperator)
bpy.types.VIEW3D_MT_object.append(add_object_menu)
def unregister():
bpy.utils.unregister_class(ExplodeOperator)
bpy.types.VIEW3D_MT_object.remove(add_object_menu)
if __name__ == '__main__':
register()
Целый шарик - это объект, для которого готовится "взрывчатый клон". Сам клон виден в виде кусочков чуть правее, кадр анимации отличается от стартового, поэтому его уже разбросало. Видно настройки оператора в Т-панели.
До кучи можно посмотреть какой на данный момент код:
bl_info = {
"name" : "ExplodeToShape",
"author" : "denis8424",
"category" : "Game Engine",
"version" : (0, 5),
}
import bpy
def main(animationProps, solidifyProps, dead_Explode, particleProps):
########################
# VAR
########################
stepA = animationProps[0]
start_Fr = animationProps[1]
end_Fr = animationProps[2]
useSolidify = solidifyProps[0]
thickness = solidifyProps[1]
count = particleProps[0]
lifetime = particleProps[1]
factor_random = particleProps[2]
factor_random = particleProps[3]
object_align_factor_X = particleProps[4]
object_align_factor_Y = particleProps[5]
object_align_factor_Z = particleProps[6]
print('<<<<<<<>>>>>>>')
object = bpy.context.object
name = object.name
listName = []
index = 0
for frame in range(start_Fr, end_Fr, stepA):
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]
bpy.ops.object.modifier_add(type = 'PARTICLE_SYSTEM')
#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)
part_S = newOb.particle_systems['ParticleSystem']
part_S.settings.frame_start = start_Fr
part_S.settings.frame_end = start_Fr
part_S.settings.count = count
part_S.settings.lifetime = lifetime
part_S.settings.object_align_factor[0] = object_align_factor_X
part_S.settings.object_align_factor[1] = object_align_factor_Y
part_S.settings.object_align_factor[2] = object_align_factor_Z
part_S.settings.factor_random = factor_random
part_S.settings.normal_factor = factor_random
part_S.settings.integrator = 'EULER'
bpy.ops.object.modifier_add(type = 'EXPLODE')
newOb.modifiers['Explode'].show_dead = dead_Explode
bpy.context.scene.frame_current = frame
bpy.ops.object.modifier_apply(modifier = 'Explode')
bpy.ops.object.particle_system_remove()
if useSolidify == True:
bpy.ops.object.modifier_add(type = 'SOLIDIFY')
newOb.modifiers['Solidify'].thickness = thickness
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:
#print(name)
# пропускаем первого клона, на него будем писать ключи формы
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-stepA), (1.0, frame), (0.0, frame+stepA)]
# И по этому списку задаем ключи анимации ключам формы
for J in frameList:
# print(J) #debug
currBlock.value = J[0]
currBlock.keyframe_insert("value", frame = J[1])
bpy.context.scene.frame_current = 1
class ExplodeOperator(bpy.types.Operator):
"""Explode object"""
bl_idname = "object.explode_operator"
bl_label = "Explode Object Operator"
bl_options = {'REGISTER', 'UNDO'}
stepA = bpy.props.IntProperty(
name = "stepA",
default = 1,
min = 1,
max = 8,
step = 1,
description = "differential"
)
start_Fr = bpy.props.IntProperty(
name = "start frame",
default = 1,
min = 1,
max = 255,
step = 1,
description = "start frame"
)
end_Fr = bpy.props.IntProperty(
name = "end_frame",
default = 8,
min = 1,
max = 255,
step = 1,
description = "end frame"
)
thickness_Solidify = bpy.props.FloatProperty(
name = "thickness_Solidify",
default = 0.05,
min = 0.01,
max = 1.0,
step = 1,
description = "Solidify thickness"
)
use_Solidify = bpy.props.BoolProperty(
name = 'use_Solidify',
default = False,
description = 'Solidify usy or not'
)
dead_Explode = bpy.props.BoolProperty(
name = 'Explode Dead',
default = False,
description = 'dead_Explode'
)
count = bpy.props.IntProperty(
name = "count",
default = 32,
min = 1,
max = 255,
step = 1,
description = "Particle Count"
)
lifetime = bpy.props.IntProperty(
name = "lifetime",
default = 50,
min = 1,
max = 255,
step = 1,
description = "Particle lifetime"
)
factor_random = bpy.props.FloatProperty(
name = "factor_random",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle random factor"
)
factor_normal = bpy.props.FloatProperty(
name = "factor_normal",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle normal factor"
)
object_align_factor_X = bpy.props.FloatProperty(
name = "object_align_factor_X",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
object_align_factor_Y = bpy.props.FloatProperty(
name = "object_align_factor_Y",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
object_align_factor_Z = bpy.props.FloatProperty(
name = "object_align_factor_Z",
default = 0.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle speed factor"
)
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
animationProps = [
self.stepA,
self.start_Fr,
self.end_Fr
]
solidifyProps = [
self.use_Solidify,
self.thickness_Solidify
]
particleProps = [
self.count,
self.lifetime,
self.factor_random,
self.factor_normal,
self.object_align_factor_X,
self.object_align_factor_Y,
self.object_align_factor_Z
]
main(
animationProps,
solidifyProps,
self.dead_Explode,
particleProps
)
return {'FINISHED'}
def draw(self, context):
layout = self.layout
layout.label(text = 'Animation:')
box = layout.box()
box.prop(self, 'stepA')
row = box.row(align = True)
row.prop(self, 'start_Fr')
row.prop(self, 'end_Fr')
layout.label(text = 'Solidify Modifier:')
box = layout.box()
row = box.row(align = True)
#row.label(text = 'Solidify:')
row.prop(self, 'use_Solidify')
if self.use_Solidify == True:
box.prop(self, 'thickness_Solidify')
# layout.label(text = 'Explode Modifier:')
# box = layout.box()
# box.prop(self, 'dead_Explode')
layout.label(text = 'Particle System:')
box = layout.box()
box.prop(self, 'count')
box.prop(self, 'lifetime')
box.prop(self, 'factor_random')
box.prop(self, 'factor_normal')
col = box.column(align = True)
col.prop(self, 'object_align_factor_X')
col.prop(self, 'object_align_factor_Y')
col.prop(self, 'object_align_factor_Z')
def add_object_menu(self, context):
self.layout.separator()
self.layout.operator(
ExplodeOperator.bl_idname,
text = ExplodeOperator.__doc__)
self.layout.label(text = 'EXPLODEEEEE!!!!')
self.layout.separator()
def register():
bpy.utils.register_class(ExplodeOperator)
bpy.types.VIEW3D_MT_object.append(add_object_menu)
def unregister():
bpy.utils.unregister_class(ExplodeOperator)
bpy.types.VIEW3D_MT_object.remove(add_object_menu)
if __name__ == '__main__':
register()
Комментариев нет:
Отправить комментарий