Add Lattice Magic
to Addons
#48
17
__init__.py
17
__init__.py
@ -31,6 +31,19 @@ from . import operators
|
|||||||
from . import utils # Just for importlib.reload()
|
from . import utils # Just for importlib.reload()
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.types import AddonPreferences
|
||||||
|
from bpy.props import BoolProperty
|
||||||
|
|
||||||
|
class LatticeMagicPreferences(AddonPreferences):
|
||||||
|
bl_idname = __name__
|
||||||
|
|
||||||
|
update_active_shape_key: BoolProperty(
|
||||||
|
name = 'Update Active Shape Key',
|
||||||
|
description = "Update the active shape key on frame change based on the current frame and the shape key's name.",
|
||||||
|
default = False
|
||||||
|
)
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
camera_lattice
|
camera_lattice
|
||||||
,tweak_lattice
|
,tweak_lattice
|
||||||
@ -39,12 +52,16 @@ modules = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
from bpy.utils import register_class
|
||||||
|
register_class(LatticeMagicPreferences)
|
||||||
for m in modules:
|
for m in modules:
|
||||||
importlib.reload(m)
|
importlib.reload(m)
|
||||||
if hasattr(m, 'register'):
|
if hasattr(m, 'register'):
|
||||||
m.register()
|
m.register()
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
from bpy.utils import unregister_class
|
||||||
|
unregister_class(LatticeMagicPreferences)
|
||||||
for m in modules:
|
for m in modules:
|
||||||
m.unregister()
|
m.unregister()
|
||||||
if hasattr(m, 'unregister'):
|
if hasattr(m, 'unregister'):
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import math
|
import math
|
||||||
|
from bpy.app.handlers import persistent
|
||||||
from mathutils import Vector
|
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
|
||||||
@ -499,10 +500,11 @@ class CAMLAT_PT_Main(bpy.types.Panel):
|
|||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator('lattice.reset_points', text="", icon='RECOVER_LAST')
|
|
||||||
row.separator()
|
|
||||||
row.operator(CAMLAT_OT_ShapeKey_Zero_All.bl_idname, text="", icon='RADIOBUT_OFF')
|
row.operator(CAMLAT_OT_ShapeKey_Zero_All.bl_idname, text="", icon='RADIOBUT_OFF')
|
||||||
row.operator(CAMLAT_OT_ShapeKey_Keyframe_All.bl_idname, text="", icon='HANDLETYPE_FREE_VEC')
|
row.operator(CAMLAT_OT_ShapeKey_Keyframe_All.bl_idname, text="", icon='HANDLETYPE_FREE_VEC')
|
||||||
|
row.separator()
|
||||||
|
prefs = context.preferences.addons[__package__].preferences
|
||||||
|
row.prop(prefs, 'update_active_shape_key', toggle=True, text="", icon='TIME')
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
@ -526,6 +528,42 @@ class CAMLAT_PT_Main(bpy.types.Panel):
|
|||||||
move_down_op = col.operator('object.shape_key_move', text="", icon='TRIA_DOWN')
|
move_down_op = col.operator('object.shape_key_move', text="", icon='TRIA_DOWN')
|
||||||
move_down_op.type='DOWN'
|
move_down_op.type='DOWN'
|
||||||
|
|
||||||
|
@persistent
|
||||||
|
def camera_lattice_frame_change(scene):
|
||||||
|
"""On frame change, set the active shape key of the active lattice object to the most recent frame
|
||||||
|
|
||||||
|
(Assuming the shape keys are named after the frame on which they are used)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# I wonder why this function doesn't recieve a context... should it not be relied on from here? o.0
|
||||||
|
context = bpy.context
|
||||||
|
|
||||||
|
prefs = context.preferences.addons[__package__].preferences
|
||||||
|
if not prefs.update_active_shape_key: return
|
||||||
|
|
||||||
|
ob = context.object
|
||||||
|
if not shape_key_poll(context):
|
||||||
|
return
|
||||||
|
|
||||||
|
key_blocks = ob.data.shape_keys.key_blocks
|
||||||
|
|
||||||
|
current_frame = scene.frame_current
|
||||||
|
most_recent_number = 0
|
||||||
|
most_recent_index = 1
|
||||||
|
for i, kb in enumerate(key_blocks):
|
||||||
|
if not kb.name.startswith('Frame '): continue
|
||||||
|
number_str = kb.name[5:].split(".")[0]
|
||||||
|
if number_str=="": continue
|
||||||
|
number = int(number_str)
|
||||||
|
if number <= current_frame and number >= most_recent_number:
|
||||||
|
most_recent_number = number
|
||||||
|
most_recent_index = i
|
||||||
|
if most_recent_number == current_frame:
|
||||||
|
break
|
||||||
|
|
||||||
|
if ob.active_shape_key_index != most_recent_index:
|
||||||
|
ob.active_shape_key_index = most_recent_index
|
||||||
|
|
||||||
classes = [
|
classes = [
|
||||||
LatticeSlot
|
LatticeSlot
|
||||||
,CAMLAT_UL_lattice_slots
|
,CAMLAT_UL_lattice_slots
|
||||||
@ -551,6 +589,7 @@ def register():
|
|||||||
|
|
||||||
bpy.types.Scene.lattice_slots = CollectionProperty(type=LatticeSlot)
|
bpy.types.Scene.lattice_slots = CollectionProperty(type=LatticeSlot)
|
||||||
bpy.types.Scene.active_lattice_index = IntProperty()
|
bpy.types.Scene.active_lattice_index = IntProperty()
|
||||||
|
bpy.app.handlers.frame_change_post.append(camera_lattice_frame_change)
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
from bpy.utils import unregister_class
|
from bpy.utils import unregister_class
|
||||||
@ -559,3 +598,5 @@ def unregister():
|
|||||||
|
|
||||||
del bpy.types.Scene.lattice_slots
|
del bpy.types.Scene.lattice_slots
|
||||||
del bpy.types.Scene.active_lattice_index
|
del bpy.types.Scene.active_lattice_index
|
||||||
|
|
||||||
|
bpy.app.handlers.frame_change_post.remove(camera_lattice_frame_change)
|
Loading…
Reference in New Issue
Block a user