diff --git a/animation_animall.py b/animation_animall.py index 309141a95101fb30d31f19aa8ab3d0b5a7ed21b2..fe99019c886069f62c4eeb10cc2bf993ffa66e9f 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, 0), + "blender": (3, 3, 0), "location": "3D View > Toolbox > Animation tab > AnimAll", "description": "Allows animation of mesh, lattice, curve and surface data", "warning": "", @@ -72,6 +72,11 @@ class AnimallProperties(bpy.types.PropertyGroup): 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 +127,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): @@ -163,6 +174,8 @@ class VIEW3D_PT_animall(Panel): row = col.row() row.prop(animall_properties, "key_vcols") row.prop(animall_properties, "key_vgroups") + row = col.row() + row.prop(animall_properties, "key_attribute") elif obj.type == 'CURVE': row.prop(animall_properties, "key_points") @@ -328,8 +341,38 @@ class ANIM_OT_insert_keyframe_animall(Operator): 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) + for v_i, vcol_data in enumerate(v_col_layer.data): + insert_key(vcol_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... @@ -429,8 +472,47 @@ class ANIM_OT_delete_keyframe_animall(Operator): 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') + for vcol_data in v_col_layer.data: + delete_key(vcol_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}') + + 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): + delete_key(data, f'attributes["{attribute.name}"].data[{e_i}].{attribute_key}') elif obj.type == 'LATTICE': if animall_properties.key_shape: