diff options
Diffstat (limited to 'animation_animall.py')
-rw-r--r-- | animation_animall.py | 119 |
1 files changed, 101 insertions, 18 deletions
diff --git a/animation_animall.py b/animation_animall.py index 309141a9..a7d76f53 100644 --- a/animation_animall.py +++ b/animation_animall.py @@ -3,8 +3,8 @@ bl_info = { "name": "AnimAll", "author": "Daniel Salazar <zanqdo@gmail.com>", - "version": (0, 8, 3), - "blender": (2, 80, 0), + "version": (0, 9, 1), + "blender": (3, 3, 0), "location": "3D View > Toolbox > Animation tab > AnimAll", "description": "Allows animation of mesh, lattice, curve and surface data", "warning": "", @@ -62,16 +62,16 @@ class AnimallProperties(bpy.types.PropertyGroup): description="Insert keyframes on edge creases", default=False ) - key_vcols: BoolProperty( - name="V-Cols", - description="Insert keyframes on active Vertex Color values", - default=False - ) key_vgroups: BoolProperty( name="V-groups", description="Insert keyframes on active Vertex group values", default=False ) + key_attribute: BoolProperty( + name="Active Attribute", + description="Insert keyframes on active attribute values", + default=False + ) key_points: BoolProperty( name="Points", description="Insert keyframes on point locations", @@ -122,6 +122,12 @@ def delete_key(data, key): pass +def is_selected_vert_loop(data, loop_i): + """Get selection status of vertex corresponding to a loop""" + vertex_index = data.loops[loop_i].vertex_index + return data.vertices[vertex_index].select + + # GUI (Panel) class VIEW3D_PT_animall(Panel): @@ -161,9 +167,23 @@ class VIEW3D_PT_animall(Panel): row.prop(animall_properties, "key_crease") row.prop(animall_properties, "key_uvs") row = col.row() - row.prop(animall_properties, "key_vcols") + row.prop(animall_properties, "key_attribute") row.prop(animall_properties, "key_vgroups") + # Vertex group update operator + if (context.active_object is not None + and context.active_object.type == 'MESH' + and context.active_object.data.animation_data is not None + and context.active_object.data.animation_data.action is not None): + for fcurve in context.active_object.data.animation_data.action.fcurves: + if fcurve.data_path.startswith("vertex_colors"): + layout.separator() + row = layout.row() + row.label(text="Object includes old-style vertex colors. Consider updating them.", icon="ERROR") + row = layout.row() + row.operator("anim.update_vertex_color_animation_animall", icon="FILE_REFRESH") + break + elif obj.type == 'CURVE': row.prop(animall_properties, "key_points") row.prop(animall_properties, "key_shape") @@ -325,11 +345,35 @@ class ANIM_OT_insert_keyframe_animall(Operator): if not animall_properties.key_selected or uv.select: insert_key(uv, 'uv', group="UV layer %s" % uv_i) - if animall_properties.key_vcols: - for v_col_layer in data.vertex_colors: - if v_col_layer.active: # only insert in active VCol layer - for v_i, data in enumerate(v_col_layer.data): - insert_key(data, 'color', group="Loop %s" % v_i) + if animall_properties.key_attribute: + if data.attributes.active is not None: + attribute = data.attributes.active + if attribute.data_type != 'STRING': + # Cannot animate string attributes? + if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}: + attribute_key = "value" + elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}: + attribute_key = "color" + elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}: + attribute_key = "vector" + + if attribute.domain == 'POINT': + group = "Vertex %s" + elif attribute.domain == 'EDGE': + group = "Edge %s" + elif attribute.domain == 'FACE': + group = "Face %s" + elif attribute.domain == 'CORNER': + group = "Loop %s" + + for e_i, _attribute_data in enumerate(attribute.data): + if (not animall_properties.key_selected + or attribute.domain == 'POINT' and data.vertices[e_i].select + or attribute.domain == 'EDGE' and data.edges[e_i].select + or attribute.domain == 'FACE' and data.polygons[e_i].select + or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)): + insert_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}', + group=group % e_i) elif obj.type in {'CURVE', 'SURFACE'}: # Shape key keys have to be inserted in object mode for curves... @@ -426,11 +470,25 @@ class ANIM_OT_delete_keyframe_animall(Operator): if not animall_properties.key_selected or uv.select: delete_key(uv, 'uv') - if animall_properties.key_vcols: - for v_col_layer in data.vertex_colors: - if v_col_layer.active: # only delete in active VCol layer - for data in v_col_layer.data: - delete_key(data, 'color') + if animall_properties.key_attribute: + if data.attributes.active is not None: + attribute = data.attributes.active + if attribute.data_type != 'STRING': + # Cannot animate string attributes? + if attribute.data_type in {'FLOAT', 'INT', 'BOOLEAN', 'INT8'}: + attribute_key = "value" + elif attribute.data_type in {'FLOAT_COLOR', 'BYTE_COLOR'}: + attribute_key = "color" + elif attribute.data_type in {'FLOAT_VECTOR', 'FLOAT2'}: + attribute_key = "vector" + + for e_i, _attribute_data in enumerate(attribute.data): + if (not animall_properties.key_selected + or attribute.domain == 'POINT' and data.vertices[e_i].select + or attribute.domain == 'EDGE' and data.edges[e_i].select + or attribute.domain == 'FACE' and data.polygons[e_i].select + or attribute.domain == 'CORNER' and is_selected_vert_loop(data, e_i)): + delete_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}') elif obj.type == 'LATTICE': if animall_properties.key_shape: @@ -517,6 +575,29 @@ class ANIM_OT_clear_animation_animall(Operator): return {'FINISHED'} +class ANIM_OT_update_vertex_color_animation_animall(Operator): + bl_label = "Update Vertex Color Animation" + bl_idname = "anim.update_vertex_color_animation_animall" + bl_description = "Update old vertex color channel formats from pre-3.3 versions" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(self, context): + if (context.active_object is None + or context.active_object.type != 'MESH' + or context.active_object.data.animation_data is None + or context.active_object.data.animation_data.action is None): + return False + for fcurve in context.active_object.data.animation_data.action.fcurves: + if fcurve.data_path.startswith("vertex_colors"): + return True + + def execute(self, context): + for fcurve in context.active_object.data.animation_data.action.fcurves: + if fcurve.data_path.startswith("vertex_colors"): + fcurve.data_path = fcurve.data_path.replace("vertex_colors", "attributes") + return {'FINISHED'} + # Add-ons Preferences Update Panel # Define Panel classes for updating @@ -569,6 +650,7 @@ def register(): bpy.utils.register_class(ANIM_OT_insert_keyframe_animall) bpy.utils.register_class(ANIM_OT_delete_keyframe_animall) bpy.utils.register_class(ANIM_OT_clear_animation_animall) + bpy.utils.register_class(ANIM_OT_update_vertex_color_animation_animall) bpy.utils.register_class(AnimallAddonPreferences) update_panel(None, bpy.context) @@ -580,6 +662,7 @@ def unregister(): bpy.utils.unregister_class(ANIM_OT_insert_keyframe_animall) bpy.utils.unregister_class(ANIM_OT_delete_keyframe_animall) bpy.utils.unregister_class(ANIM_OT_clear_animation_animall) + bpy.utils.unregister_class(ANIM_OT_update_vertex_color_animation_animall) bpy.utils.unregister_class(AnimallAddonPreferences) if __name__ == "__main__": |