Внезапно всё пошло, причем почти сразу же после написания предыдущего поста. Логику добавления системы частиц я поменял, еще кое-какие изменения есть. По сути эта версия уже Бета, основной функционал готов, осталось только напильником пройтись, попереименовывать некоторые переменные, определиться с диапазоном их изменения, возможно добавить еще каких настроек, или наоборот, какие-то настройки убрать. Еще добавить всякие подсказки, короче красиво оформить. Да, проверку типа объекта надо сделать, чтобы оно не пыталось взорвать лампочку, к примеру.
Долго провозился с системой частиц, сразу всем хочу сказать, не надо для изменения текущего кадра в сцене использовать scene.frame_current, оно так не работает, система частиц плевать хотела на такое изменение, юзайте scene.frame_set(), если бы я сразу им воспользовался, то пару дней не провозился бы.
Ниже код, какой он есть сейчас. ДЛИННОТА!
bl_info = {
"name" : "ExplodeToShape",
"author" : "denis8424",
"category" : "Animation",
"version" : (0, 7),
}
import bpy
def main(animationProps, solidifyProps, dead_Explode, particleProps):
print('<<<<<<<>>>>>>>') # это чтобы в консоли отличать сообщения между
# разными запусками оператора
########################
# VAR
########################
# выковыриваем из списков переменные. Списки, чтобы вызов функции
# был короче, оно в принципе не обязательно, просто я лентяй
# количество кадров, приходящееся на один ключ
frameWithAKey = animationProps[0]
# стартовый кадр анимации
startFr = animationProps[1]
# конечный кадр анимации
end_Fr = animationProps[2]
# использовать ли модификатор Твердости
useSolidify = solidifyProps[0]
# параметр толщины вышеупомянутого модификатора Твердости
thickness = solidifyProps[1]
# Теперь пошли настройки системы частиц
# количество "кусков"
count = particleProps[0]
# время жизни частиц
lifetime = particleProps[1]
# Эти два параметра управляют индивидуальной скоростью разлета осколков
# направление задается случайным образом
factor_random = particleProps[2]
# направление задается от нормали
factor_normal = particleProps[3]
# А эти три - задают общий для всех обломков вектор полета
object_align_factor_X = particleProps[4]
object_align_factor_Y = particleProps[5]
object_align_factor_Z = particleProps[6]
# выковыриваем из контекста нужные данные
# текущая сцена
scene = bpy.context.scene
# объект, для которого вызывается оператор
object = bpy.context.object
# имя объекта, нужно для задания имен ключам
name = object.name
# создаем список имен используемых объектов
# формат - [имя, соответствующий кадр анимации, индекс в списке]
listNames = []
# сразу создаем переменную индекса, надо будет посмотреть, может её выкинуть
index = 0
# Вот теперь пошла работа
# Создаем клон нашего объекта
bpy.ops.object.duplicate()
# Получаем его, он будет клонироваться, на нем висят все модификаторы и он
# же отвечает за форму базового ключа
basisOb = scene.objects.active
# переименовываем нашу основу
basisOb.name = name + ' BasisExplode'
# добавляем модификатор системы частиц
bpy.ops.object.modifier_add(type = 'PARTICLE_SYSTEM')
# получаем добавленную систему частиц
part_S = basisOb.particle_systems['ParticleSystem']
# и настраиваем её, переменные мы знаем
# начало и конец испускания частиц должны быть одинаковы!
part_S.settings.frame_start = startFr
part_S.settings.frame_end = startFr
part_S.settings.count = count
part_S.settings.lifetime = lifetime
part_S.settings.factor_random = factor_random
part_S.settings.normal_factor = factor_normal
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.integrator = 'EULER'
part_S.settings.use_modifier_stack = True
# Надо наверное сделать возможность смены типа физики частиц
part_S.settings.physics_type = 'NEWTON'
# Теперь добавляем модификатор взрыва
bpy.ops.object.modifier_add(type = 'EXPLODE')
# И модификатор "Твердости", если таковая галочка установлена
if useSolidify == True:
bpy.ops.object.modifier_add(type = 'SOLIDIFY')
basisOb.modifiers['Solidify'].thickness = 0.1
# добавляем базовый объект в список имен
listNames.append((basisOb.name, startFr, index))
# Теперь будем клонировать некоторое количество раз наш базовый объект
for frame in range(startFr + frameWithAKey, end_Fr + frameWithAKey, frameWithAKey):
# в процессе рассчитываем ключевые кадры
# поскольку это цикл, то после копирования активным станет новый клон,
# поэтому снова делаем активным базовый объект
scene.objects.active = basisOb
# выбираем базовый объект
basisOb.select = True
# клонируем его
bpy.ops.object.duplicate()
# получаем новую копию
newOb = scene.objects.active
# и переименовываем
newOb.name = name + ' Explode' + str(frame)
# увеличиваем индекс на 1
index = index + 1
# добавляем имя клона, кадр анимации и индекс в список имен
listNames.append((newOb.name, frame, index))
# снимаем выбор со всех объектов
bpy.ops.object.select_all(action = 'DESELECT')
# Теперь достаем из списка имя клона и связанный с ним номер кадра
for name, frame, index in listNames:
# устанавливаем текущий кадр в сцене
scene.frame_set(frame, 0.0)
# получаем текущий объект из сцены по имени
currOb = scene.objects[name]
# делаем его активным и выбираем
scene.objects.active = currOb
currOb.select = True
# а теперь применяем модификаторы
# сначала модификатор взрыва
bpy.ops.object.modifier_apply(modifier = 'Explode', apply_as = 'DATA')
# потом удаляем систему частиц
bpy.ops.object.particle_system_remove()
# и если мы выбрали "твердость" обломков
if useSolidify == True:
# то применяем и этот модификатор
bpy.ops.object.modifier_apply(modifier = 'Solidify')
# снимаем выделение
bpy.ops.object.select_all(action = 'DESELECT')
#print(listNames)
# Здесь будем добавлять клонов как ключи формы, причем самому первому клону,
# потому что нельзя добавить объект в ключи другому объекту, если у них
# разное число вершин.
for name, frame, index in listNames:
#print(name)
# пропускаем первого клона, он же базовый, на него будем писать ключи
# формы
if index == 0:
continue
else:
# понятно, выковыриваем клон(не первый) по имени, он пойдет
# в ключ формы
currObj = bpy.context.scene.objects[name]
# выбираем его
currObj.select = True
# получаем первого клона
explObject = bpy.context.scene.objects[listNames[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[listNames[0][0]]
bpy.context.scene.objects.active = objExpl
objExpl.select = True
# получаем его список ключей форм
shapeKeys = objExpl.data.shape_keys
for name, frame, index in listNames:
# достаем ключ формы по имени, на всякий случай проверяя, есть ли такой
if name in shapeKeys.key_blocks:
# текущий ключ формы
currBlock = shapeKeys.key_blocks[name]
# генерируем список из кортежей "значение - кадр"
frameList = [(0.0, frame-frameWithAKey),
(1.0, frame),
(0.0, frame+frameWithAKey)]
# И по этому списку задаем ключи анимации ключам формы
for J in frameList:
# print(J) #debug
currBlock.value = J[0]
currBlock.interpolation = 'KEY_LINEAR'
currBlock.keyframe_insert("value", frame = J[1])
# изменяем тип ключевых точек для кривых анимации
# выковыриваем циклом по одной ФКурву из списка данных анимации
for f_curve in shapeKeys.animation_data.action.fcurves:
# из ФКурвы достаем список ключевых точек и проходим по одной
for key_point in f_curve.keyframe_points:
#изменяем тип
key_point.interpolation = 'LINEAR'
# возвращаем сцену в первый кадр
bpy.context.scene.frame_set(1, 0.0)
class ExplodeOperator(bpy.types.Operator):
"""Explode object"""
bl_idname = "object.explode_operator"
bl_label = "Explode Object Operator"
bl_options = {'REGISTER', 'UNDO'}
frameWithAKey = bpy.props.IntProperty(
name = "frameWithAKey",
default = 1,
min = 1,
max = 8,
step = 1,
description = "animation frame with a shape key"
)
startFr = bpy.props.IntProperty(
name = "start frame",
default = 1,
min = 1,
max = 255,
step = 1,
description = "start animation frame"
)
end_Fr = bpy.props.IntProperty(
name = "end_frame",
default = 8,
min = 1,
max = 255,
step = 1,
description = "end animation 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 = 1.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle random factor"
)
factor_normal = bpy.props.FloatProperty(
name = "factor_normal",
default = 1.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 = -255.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 = -255.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 = -255.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.frameWithAKey,
self.startFr,
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, 'frameWithAKey')
row = box.row(align = True)
row.prop(self, 'startFr')
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.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()
Долго провозился с системой частиц, сразу всем хочу сказать, не надо для изменения текущего кадра в сцене использовать scene.frame_current, оно так не работает, система частиц плевать хотела на такое изменение, юзайте scene.frame_set(), если бы я сразу им воспользовался, то пару дней не провозился бы.
Ниже код, какой он есть сейчас. ДЛИННОТА!
bl_info = {
"name" : "ExplodeToShape",
"author" : "denis8424",
"category" : "Animation",
"version" : (0, 7),
}
import bpy
def main(animationProps, solidifyProps, dead_Explode, particleProps):
print('<<<<<<<>>>>>>>') # это чтобы в консоли отличать сообщения между
# разными запусками оператора
########################
# VAR
########################
# выковыриваем из списков переменные. Списки, чтобы вызов функции
# был короче, оно в принципе не обязательно, просто я лентяй
# количество кадров, приходящееся на один ключ
frameWithAKey = animationProps[0]
# стартовый кадр анимации
startFr = animationProps[1]
# конечный кадр анимации
end_Fr = animationProps[2]
# использовать ли модификатор Твердости
useSolidify = solidifyProps[0]
# параметр толщины вышеупомянутого модификатора Твердости
thickness = solidifyProps[1]
# Теперь пошли настройки системы частиц
# количество "кусков"
count = particleProps[0]
# время жизни частиц
lifetime = particleProps[1]
# Эти два параметра управляют индивидуальной скоростью разлета осколков
# направление задается случайным образом
factor_random = particleProps[2]
# направление задается от нормали
factor_normal = particleProps[3]
# А эти три - задают общий для всех обломков вектор полета
object_align_factor_X = particleProps[4]
object_align_factor_Y = particleProps[5]
object_align_factor_Z = particleProps[6]
# выковыриваем из контекста нужные данные
# текущая сцена
scene = bpy.context.scene
# объект, для которого вызывается оператор
object = bpy.context.object
# имя объекта, нужно для задания имен ключам
name = object.name
# создаем список имен используемых объектов
# формат - [имя, соответствующий кадр анимации, индекс в списке]
listNames = []
# сразу создаем переменную индекса, надо будет посмотреть, может её выкинуть
index = 0
# Вот теперь пошла работа
# Создаем клон нашего объекта
bpy.ops.object.duplicate()
# Получаем его, он будет клонироваться, на нем висят все модификаторы и он
# же отвечает за форму базового ключа
basisOb = scene.objects.active
# переименовываем нашу основу
basisOb.name = name + ' BasisExplode'
# добавляем модификатор системы частиц
bpy.ops.object.modifier_add(type = 'PARTICLE_SYSTEM')
# получаем добавленную систему частиц
part_S = basisOb.particle_systems['ParticleSystem']
# и настраиваем её, переменные мы знаем
# начало и конец испускания частиц должны быть одинаковы!
part_S.settings.frame_start = startFr
part_S.settings.frame_end = startFr
part_S.settings.count = count
part_S.settings.lifetime = lifetime
part_S.settings.factor_random = factor_random
part_S.settings.normal_factor = factor_normal
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.integrator = 'EULER'
part_S.settings.use_modifier_stack = True
# Надо наверное сделать возможность смены типа физики частиц
part_S.settings.physics_type = 'NEWTON'
# Теперь добавляем модификатор взрыва
bpy.ops.object.modifier_add(type = 'EXPLODE')
# И модификатор "Твердости", если таковая галочка установлена
if useSolidify == True:
bpy.ops.object.modifier_add(type = 'SOLIDIFY')
basisOb.modifiers['Solidify'].thickness = 0.1
# добавляем базовый объект в список имен
listNames.append((basisOb.name, startFr, index))
# Теперь будем клонировать некоторое количество раз наш базовый объект
for frame in range(startFr + frameWithAKey, end_Fr + frameWithAKey, frameWithAKey):
# в процессе рассчитываем ключевые кадры
# поскольку это цикл, то после копирования активным станет новый клон,
# поэтому снова делаем активным базовый объект
scene.objects.active = basisOb
# выбираем базовый объект
basisOb.select = True
# клонируем его
bpy.ops.object.duplicate()
# получаем новую копию
newOb = scene.objects.active
# и переименовываем
newOb.name = name + ' Explode' + str(frame)
# увеличиваем индекс на 1
index = index + 1
# добавляем имя клона, кадр анимации и индекс в список имен
listNames.append((newOb.name, frame, index))
# снимаем выбор со всех объектов
bpy.ops.object.select_all(action = 'DESELECT')
# Теперь достаем из списка имя клона и связанный с ним номер кадра
for name, frame, index in listNames:
# устанавливаем текущий кадр в сцене
scene.frame_set(frame, 0.0)
# получаем текущий объект из сцены по имени
currOb = scene.objects[name]
# делаем его активным и выбираем
scene.objects.active = currOb
currOb.select = True
# а теперь применяем модификаторы
# сначала модификатор взрыва
bpy.ops.object.modifier_apply(modifier = 'Explode', apply_as = 'DATA')
# потом удаляем систему частиц
bpy.ops.object.particle_system_remove()
# и если мы выбрали "твердость" обломков
if useSolidify == True:
# то применяем и этот модификатор
bpy.ops.object.modifier_apply(modifier = 'Solidify')
# снимаем выделение
bpy.ops.object.select_all(action = 'DESELECT')
#print(listNames)
# Здесь будем добавлять клонов как ключи формы, причем самому первому клону,
# потому что нельзя добавить объект в ключи другому объекту, если у них
# разное число вершин.
for name, frame, index in listNames:
#print(name)
# пропускаем первого клона, он же базовый, на него будем писать ключи
# формы
if index == 0:
continue
else:
# понятно, выковыриваем клон(не первый) по имени, он пойдет
# в ключ формы
currObj = bpy.context.scene.objects[name]
# выбираем его
currObj.select = True
# получаем первого клона
explObject = bpy.context.scene.objects[listNames[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[listNames[0][0]]
bpy.context.scene.objects.active = objExpl
objExpl.select = True
# получаем его список ключей форм
shapeKeys = objExpl.data.shape_keys
for name, frame, index in listNames:
# достаем ключ формы по имени, на всякий случай проверяя, есть ли такой
if name in shapeKeys.key_blocks:
# текущий ключ формы
currBlock = shapeKeys.key_blocks[name]
# генерируем список из кортежей "значение - кадр"
frameList = [(0.0, frame-frameWithAKey),
(1.0, frame),
(0.0, frame+frameWithAKey)]
# И по этому списку задаем ключи анимации ключам формы
for J in frameList:
# print(J) #debug
currBlock.value = J[0]
currBlock.interpolation = 'KEY_LINEAR'
currBlock.keyframe_insert("value", frame = J[1])
# изменяем тип ключевых точек для кривых анимации
# выковыриваем циклом по одной ФКурву из списка данных анимации
for f_curve in shapeKeys.animation_data.action.fcurves:
# из ФКурвы достаем список ключевых точек и проходим по одной
for key_point in f_curve.keyframe_points:
#изменяем тип
key_point.interpolation = 'LINEAR'
# возвращаем сцену в первый кадр
bpy.context.scene.frame_set(1, 0.0)
class ExplodeOperator(bpy.types.Operator):
"""Explode object"""
bl_idname = "object.explode_operator"
bl_label = "Explode Object Operator"
bl_options = {'REGISTER', 'UNDO'}
frameWithAKey = bpy.props.IntProperty(
name = "frameWithAKey",
default = 1,
min = 1,
max = 8,
step = 1,
description = "animation frame with a shape key"
)
startFr = bpy.props.IntProperty(
name = "start frame",
default = 1,
min = 1,
max = 255,
step = 1,
description = "start animation frame"
)
end_Fr = bpy.props.IntProperty(
name = "end_frame",
default = 8,
min = 1,
max = 255,
step = 1,
description = "end animation 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 = 1.0,
min = 0.0,
max = 255.0,
step = 1.0,
description = "Particle random factor"
)
factor_normal = bpy.props.FloatProperty(
name = "factor_normal",
default = 1.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 = -255.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 = -255.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 = -255.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.frameWithAKey,
self.startFr,
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, 'frameWithAKey')
row = box.row(align = True)
row.prop(self, 'startFr')
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.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()
Комментариев нет:
Отправить комментарий