Add Lattice Magic to Addons #48

Merged
Nick Alberelli merged 36 commits from feature/lattice_magic into main 2023-05-17 20:48:52 +02:00
3 changed files with 36 additions and 14 deletions
Showing only changes of commit 80361a1868 - Show all commits

View File

@ -14,7 +14,7 @@ from mathutils import Vector
from bpy.props import BoolProperty, PointerProperty, CollectionProperty, IntProperty, EnumProperty, FloatProperty from bpy.props import BoolProperty, PointerProperty, CollectionProperty, IntProperty, EnumProperty, FloatProperty
from mathutils.geometry import intersect_point_line from mathutils.geometry import intersect_point_line
from .utils import bounding_box_center, bounding_box from .utils import bounding_box_center_of_objects
class CAMLAT_UL_lattice_slots(bpy.types.UIList): class CAMLAT_UL_lattice_slots(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname): def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
@ -215,15 +215,8 @@ class CAMLAT_OT_Generate(bpy.types.Operator):
### Placing the Lattice in the center of the camera's view, at the bounding box center of the collection's objects. ### Placing the Lattice in the center of the camera's view, at the bounding box center of the collection's objects.
# Find the bounding box center of the collection of objects # Find the bounding box center of the collection of objects
all_meshes = [] all_meshes = [o for o in collection.all_objects if o.type=='MESH']
all_points = [] center = bounding_box_center_of_objects(all_meshes)
for ob in collection.all_objects:
if ob.type=='MESH' and ob not in all_meshes:
all_meshes.append(ob)
for p in ob.bound_box:
all_points.append(ob.matrix_world @ Vector(p))
center = bounding_box_center(all_points)
# Define a line from the camera towards the camera's view direction # Define a line from the camera towards the camera's view direction
cam_vec = Vector((0, 0, -1)) # Default aim vector of a camera (they point straight down) cam_vec = Vector((0, 0, -1)) # Default aim vector of a camera (they point straight down)

View File

@ -16,12 +16,12 @@
# Add operators to the UI wherever possible. # Add operators to the UI wherever possible.
import bpy import bpy
from bpy.props import FloatProperty, IntVectorProperty, FloatVectorProperty, BoolProperty, PointerProperty, StringProperty from bpy.props import FloatProperty, IntVectorProperty, FloatVectorProperty, BoolProperty, PointerProperty, StringProperty, EnumProperty
from typing import List from typing import List
from mathutils import Vector from mathutils import Vector
from rna_prop_ui import rna_idprop_ui_create from rna_prop_ui import rna_idprop_ui_create
from .utils import clamp, get_lattice_vertex_index, simple_driver from .utils import clamp, get_lattice_vertex_index, simple_driver, bounding_box_center_of_objects
coll_name = 'Tweak Lattices' coll_name = 'Tweak Lattices'
@ -137,6 +137,8 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
return False return False
def execute(self, context): def execute(self, context):
scene = context.scene
# Ensure a collection to organize all our objects in. # Ensure a collection to organize all our objects in.
coll = ensure_tweak_lattice_collection(context.scene) coll = ensure_tweak_lattice_collection(context.scene)
@ -185,7 +187,11 @@ class TWEAKLAT_OT_Create(bpy.types.Operator):
root = bpy.data.objects.new(root_name, None) root = bpy.data.objects.new(root_name, None)
root.empty_display_type = 'CUBE' root.empty_display_type = 'CUBE'
root.empty_display_size = 0.5 root.empty_display_size = 0.5
root.matrix_world = context.scene.cursor.matrix if context.scene.tweak_lattice_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:
root.matrix_world = context.scene.cursor.matrix
coll.objects.link(root) coll.objects.link(root)
root.hide_viewport = True root.hide_viewport = True
hook['Root'] = root hook['Root'] = root
@ -386,6 +392,7 @@ class TWEAKLAT_PT_Main(bpy.types.Panel):
layout = layout.column() layout = layout.column()
if hook.type!='EMPTY' or 'Tweak Lattice' not in hook: if hook.type!='EMPTY' or 'Tweak Lattice' not in hook:
scene = context.scene scene = context.scene
layout.row().prop(scene, 'tweak_lattice_location', expand=True)
layout.prop(scene, 'tweak_lattice_radius', slider=True) layout.prop(scene, 'tweak_lattice_radius', slider=True)
layout.separator() layout.separator()
layout.prop(scene, 'tweak_lattice_parent_ob') layout.prop(scene, 'tweak_lattice_parent_ob')
@ -413,6 +420,15 @@ class TWEAKLAT_PT_Main(bpy.types.Panel):
root_row.prop(hook, '["Root"]', text="Root") root_row.prop(hook, '["Root"]', text="Root")
root_row.prop(hook['Root'], 'hide_viewport', text="", emboss=False) root_row.prop(hook['Root'], 'hide_viewport', text="", emboss=False)
layout.separator()
layout.label(text="Parenting")
root = hook['Root']
col = layout.column()
col.enabled = False
col.prop(root, 'parent')
if root.parent and root.parent.type=='ARMATURE':
col.prop(root, 'parent_bone')
layout.separator() layout.separator()
layout.label(text="Add Objects") layout.label(text="Add Objects")
for o in context.selected_objects: for o in context.selected_objects:
@ -456,6 +472,10 @@ def register():
bpy.types.Scene.tweak_lattice_radius = FloatProperty(name="Radius", default=0.1, min=0.0001, max=1000, soft_max=2) bpy.types.Scene.tweak_lattice_radius = FloatProperty(name="Radius", default=0.1, min=0.0001, max=1000, soft_max=2)
bpy.types.Scene.tweak_lattice_parent_ob = PointerProperty(type=bpy.types.Object, name="Parent") # Maybe it would be safer to make this a StringProperty but whatever. bpy.types.Scene.tweak_lattice_parent_ob = PointerProperty(type=bpy.types.Object, name="Parent") # Maybe it would be safer to make this a StringProperty but whatever.
bpy.types.Scene.tweak_lattice_parent_bone = StringProperty(name="Bone") bpy.types.Scene.tweak_lattice_parent_bone = StringProperty(name="Bone")
bpy.types.Scene.tweak_lattice_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.")
])
def unregister(): def unregister():
from bpy.utils import unregister_class from bpy.utils import unregister_class
@ -465,3 +485,4 @@ def unregister():
del bpy.types.Scene.tweak_lattice_radius del bpy.types.Scene.tweak_lattice_radius
del bpy.types.Scene.tweak_lattice_parent_ob del bpy.types.Scene.tweak_lattice_parent_ob
del bpy.types.Scene.tweak_lattice_parent_bone del bpy.types.Scene.tweak_lattice_parent_bone
del bpy.types.Scene.tweak_lattice_location

View File

@ -94,3 +94,11 @@ def bounding_box_center(points) -> Vector:
"""Find the bounding box center of some points.""" """Find the bounding box center of some points."""
bbox_low, bbox_high = bounding_box(points) bbox_low, bbox_high = bounding_box(points)
return bbox_low + (bbox_high-bbox_low)/2 return bbox_low + (bbox_high-bbox_low)/2
def bounding_box_center_of_objects(objects) -> Vector:
"""Find the bounding box center of some objects."""
all_points = []
for o in objects:
for p in o.bound_box:
all_points.append(o.matrix_world @ Vector(p))
return bounding_box_center(all_points)