Add Lattice Magic
to Addons
#48
@ -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)
|
||||||
|
@ -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
|
||||||
@ -464,4 +484,5 @@ 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
|
8
utils.py
8
utils.py
@ -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)
|
Loading…
Reference in New Issue
Block a user