Add Lattice Magic
to Addons
#48
@ -134,10 +134,10 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
|
||||
max=64
|
||||
)
|
||||
|
||||
# TODO: Add an option to spawn at the location of the parent (object or bone).
|
||||
location: EnumProperty(name="Location", items=[
|
||||
('CURSOR', "3D Cursor", "Create at the location and orientation of the 3D cursor.")
|
||||
,('CENTER', "Center", "Create at the bounding box center of all selected objects.")
|
||||
,('PARENT', "Parent", "Create at the location of the parent object or bone.")
|
||||
])
|
||||
radius: FloatProperty(
|
||||
name="Radius",
|
||||
@ -161,6 +161,10 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
|
||||
for m in parent_obj.modifiers:
|
||||
if m.type == 'ARMATURE' and m.object:
|
||||
parent_obj = m.object
|
||||
if self.parent_bone not in parent_obj.data.bones:
|
||||
self.parent_bone = ""
|
||||
break
|
||||
|
||||
context.scene.tweak_lattice_parent_ob = parent_obj
|
||||
|
||||
wm = context.window_manager
|
||||
@ -237,8 +241,13 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
|
||||
if self.location == 'CENTER':
|
||||
meshes = [o for o in context.selected_objects if o.type=='MESH']
|
||||
root.matrix_world.translation = bounding_box_center_of_objects(meshes)
|
||||
else:
|
||||
elif self.location == 'CURSOR':
|
||||
root.matrix_world = context.scene.cursor.matrix
|
||||
elif self.location == 'PARENT':
|
||||
matrix_of_parent = scene.tweak_lattice_parent_ob.matrix_world
|
||||
if self.parent_bone:
|
||||
matrix_of_parent = scene.tweak_lattice_parent_ob.matrix_world @ scene.tweak_lattice_parent_ob.pose.bones[self.parent_bone].matrix
|
||||
root.matrix_world = matrix_of_parent.copy()
|
||||
coll.objects.link(root)
|
||||
root.hide_viewport = True
|
||||
hook['Root'] = root
|
||||
@ -422,7 +431,7 @@ class TWEAKLAT_OT_Add_Objects(bpy.types.Operator):
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class TWEAKLAT_OT_Remove_Objects(bpy.types.Operator):
|
||||
class TWEAKLAT_OT_Remove_Selected_Objects(bpy.types.Operator):
|
||||
"""Remove selected objects from this tweak lattice"""
|
||||
bl_idname = "lattice.remove_selected_objects"
|
||||
bl_label = "Remove Selected Objects"
|
||||
@ -447,6 +456,22 @@ class TWEAKLAT_OT_Remove_Objects(bpy.types.Operator):
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class TWEAKLAT_OT_Remove_Object(bpy.types.Operator):
|
||||
"""Remove this object from the tweak lattice"""
|
||||
bl_idname = "lattice.remove_object"
|
||||
bl_label = "Remove Object"
|
||||
bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
|
||||
|
||||
ob_pointer_prop_name: StringProperty(description="Name of the custom property that references the object that should be removed")
|
||||
|
||||
def execute(self, context):
|
||||
hook = context.object
|
||||
target = hook[self.ob_pointer_prop_name]
|
||||
|
||||
# Add Lattice modifier to the selected objects
|
||||
remove_objects_from_lattice(hook, [target])
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class TWEAKLAT_PT_Main(bpy.types.Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
@ -493,27 +518,36 @@ class TWEAKLAT_PT_Main(bpy.types.Panel):
|
||||
col.enabled = False
|
||||
col.prop(root, 'parent')
|
||||
if root.parent and root.parent.type=='ARMATURE':
|
||||
col.prop(root, 'parent_bone')
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Add Objects")
|
||||
for o in context.selected_objects:
|
||||
if o == hook or o.type!='MESH': continue
|
||||
if o in hook.values(): continue
|
||||
layout.label(text=o.name, icon='ADD')
|
||||
layout.operator(TWEAKLAT_OT_Add_Objects.bl_idname, icon='ADD')
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Remove Objects")
|
||||
for o in context.selected_objects:
|
||||
if o == hook or o.type!='MESH': continue
|
||||
if o not in hook.values(): continue
|
||||
layout.label(text=o.name, icon='REMOVE')
|
||||
layout.operator(TWEAKLAT_OT_Remove_Objects.bl_idname, icon='REMOVE')
|
||||
col.prop(root, 'parent_bone', icon='BONE_DATA')
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Affected Objects")
|
||||
|
||||
num_to_add = 0
|
||||
for o in context.selected_objects:
|
||||
if o == hook or o.type!='MESH': continue
|
||||
if o in hook.values(): continue
|
||||
num_to_add += 1
|
||||
if num_to_add == 1:
|
||||
text = f"Add {o.name}"
|
||||
if num_to_add:
|
||||
if num_to_add > 1:
|
||||
text = f"Add {num_to_add} Objects"
|
||||
layout.operator(TWEAKLAT_OT_Add_Objects.bl_idname, icon='ADD', text=text)
|
||||
|
||||
layout.separator()
|
||||
num_to_remove = False
|
||||
for o in context.selected_objects:
|
||||
if o == hook or o.type!='MESH': continue
|
||||
if o not in hook.values(): continue
|
||||
num_to_remove += 1
|
||||
if num_to_remove == 1:
|
||||
text = f"Remove {o.name}"
|
||||
if num_to_remove:
|
||||
if num_to_remove > 1:
|
||||
text = f"Remove {num_to_remove} Objects"
|
||||
layout.operator(TWEAKLAT_OT_Remove_Selected_Objects.bl_idname, icon='REMOVE', text=text)
|
||||
|
||||
objects_and_keys = [(hook[key], key) for key in hook.keys() if "object_" in key]
|
||||
objects_and_keys.sort(key=lambda o_and_k: o_and_k[1])
|
||||
for ob, key in objects_and_keys:
|
||||
@ -521,6 +555,8 @@ class TWEAKLAT_PT_Main(bpy.types.Panel):
|
||||
row.prop(hook, f'["{key}"]', text="")
|
||||
mod = get_lattice_modifier_of_object(ob, hook['Lattice'])
|
||||
row.prop_search(mod, 'vertex_group', ob, 'vertex_groups', text="", icon='GROUP_VERTEX')
|
||||
op = row.operator(TWEAKLAT_OT_Remove_Object.bl_idname, text="", icon='X')
|
||||
op.ob_pointer_prop_name = key
|
||||
|
||||
|
||||
classes = [
|
||||
@ -528,7 +564,8 @@ classes = [
|
||||
,TWEAKLAT_OT_Delete
|
||||
,TWEAKLAT_OT_Falloff
|
||||
,TWEAKLAT_OT_Add_Objects
|
||||
,TWEAKLAT_OT_Remove_Objects
|
||||
,TWEAKLAT_OT_Remove_Selected_Objects
|
||||
,TWEAKLAT_OT_Remove_Object
|
||||
,TWEAKLAT_PT_Main
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user