From 52a2a761c49ab59842b440990a3b58bccfbb3dab Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Wed, 24 Feb 2021 16:14:58 +0100 Subject: Object Color Rules: fix object selection --- object_color_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object_color_rules.py b/object_color_rules.py index 52011366..f404c06e 100644 --- a/object_color_rules.py +++ b/object_color_rules.py @@ -172,7 +172,7 @@ def object_colors_select(rule, objects): test_cb = getattr(rule_test, rule_type) for obj in objects: - obj.select = test_cb(obj, rule, cache) + obj.select_set(test_cb(obj, rule, cache)) def object_colors_rule_validate(rule, report): -- cgit v1.2.3 From a45df1532510c09ea5430a012f3ce5c48711f29c Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 29 Mar 2021 11:33:56 +0200 Subject: Add camera rigs: fix poll method when not created with add-on When creating an armature containing a camera, without the add-on, the UI panel tries to display, but the data is not set up to use it properly. --- add_camera_rigs/operators.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/add_camera_rigs/operators.py b/add_camera_rigs/operators.py index 646566ae..18300e08 100644 --- a/add_camera_rigs/operators.py +++ b/add_camera_rigs/operators.py @@ -5,7 +5,10 @@ from bpy.types import Operator def get_rig_and_cam(obj): - if obj.type == 'ARMATURE': + if (obj.type == 'ARMATURE' + and "rig_id" in obj + and obj["rig_id"].lower() in {"dolly_rig", + "crane_rig", "2d_rig"}): cam = None for child in obj.children: if child.type == 'CAMERA': -- cgit v1.2.3 From d0e2d121b72a3f042a669186abedfdb0974b4202 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 22 Nov 2021 10:32:19 +0100 Subject: Node Wrangler: make preference hotkey list filter update interactively --- node_wrangler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node_wrangler.py b/node_wrangler.py index f2280f2c..7e1e932e 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -1165,7 +1165,8 @@ class NWNodeWrangler(bpy.types.AddonPreferences): hotkey_list_filter: StringProperty( name=" Filter by Name", default="", - description="Show only hotkeys that have this text in their name" + description="Show only hotkeys that have this text in their name", + options={'TEXTEDIT_UPDATE'} ) show_principled_lists: BoolProperty( name="Show Principled naming tags", -- cgit v1.2.3 From 67273f17e8a5bf845e44e32e72071008e3369e36 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Thu, 2 Jun 2022 11:43:03 +0200 Subject: Fix T92871: Node Wrangler: connect to output shortcut in Geo Node This implements the use of shortcut `O` to connect the first geometry output of the active node, to the group output. Right now, only geometry is concerned, and the operator is cancelled if another output type is found, such as an `int`. --- node_wrangler.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/node_wrangler.py b/node_wrangler.py index 7e1e932e..30331ce2 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -3748,7 +3748,7 @@ class NWLinkToOutputNode(Operator): @classmethod def poll(cls, context): valid = False - if nw_check(context) and context.space_data.tree_type != 'GeometryNodeTree': + if nw_check(context): if context.active_node is not None: for out in context.active_node.outputs: if is_visible_socket(out): @@ -3762,11 +3762,14 @@ class NWLinkToOutputNode(Operator): output_node = None output_index = None tree_type = context.space_data.tree_type - output_types_shaders = [x[1] for x in shaders_output_nodes_props] - output_types_compo = ['COMPOSITE'] - output_types_blender_mat = ['OUTPUT'] - output_types_textures = ['OUTPUT'] - output_types = output_types_shaders + output_types_compo + output_types_blender_mat + if tree_type == 'ShaderNodeTree': + output_types = [x[1] for x in shaders_output_nodes_props] + ['OUTPUT'] + elif tree_type == 'CompositorNodeTree': + output_types = ['COMPOSITE'] + elif tree_type == 'TextureNodeTree': + output_types = ['OUTPUT'] + elif tree_type == 'GeometryNodeTree': + output_types = ['GROUP_OUTPUT'] for node in nodes: if node.type in output_types: output_node = node @@ -3779,6 +3782,8 @@ class NWLinkToOutputNode(Operator): output_node = nodes.new('CompositorNodeComposite') elif tree_type == 'TextureNodeTree': output_node = nodes.new('TextureNodeOutput') + elif tree_type == 'GeometryNodeTree': + output_node = nodes.new('NodeGroupOutput') output_node.location.x = active.location.x + active.dimensions.x + 80 output_node.location.y = active.location.y if (output_node and active.outputs): @@ -3797,6 +3802,9 @@ class NWLinkToOutputNode(Operator): out_input_index = 1 elif active.outputs[output_index].type != 'SHADER': # connect to displacement if not a shader out_input_index = 2 + elif tree_type == 'GeometryNodeTree': + if active.outputs[output_index].type != 'GEOMETRY': + return {'CANCELLED'} links.new(active.outputs[output_index], output_node.inputs[out_input_index]) force_update(context) # viewport render does not update -- cgit v1.2.3 From ebe0bd5677af5810972feb212a027b2a30f1ee6a Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Thu, 2 Jun 2022 11:48:17 +0200 Subject: Node Wrangler: create world output if the node tree is of type world When using the node.nw_link_out operator (O key) in a world node tree, a material output would be created instead of a world one. --- node_wrangler.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/node_wrangler.py b/node_wrangler.py index 30331ce2..1a815dc6 100644 --- a/node_wrangler.py +++ b/node_wrangler.py @@ -3777,7 +3777,10 @@ class NWLinkToOutputNode(Operator): if not output_node: bpy.ops.node.select_all(action="DESELECT") if tree_type == 'ShaderNodeTree': - output_node = nodes.new('ShaderNodeOutputMaterial') + if context.space_data.shader_type == 'OBJECT': + output_node = nodes.new('ShaderNodeOutputMaterial') + elif context.space_data.shader_type == 'WORLD': + output_node = nodes.new('ShaderNodeOutputWorld') elif tree_type == 'CompositorNodeTree': output_node = nodes.new('CompositorNodeComposite') elif tree_type == 'TextureNodeTree': -- cgit v1.2.3 From b91319aead96a5f6eaa11728626765dc288e8649 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 13 Jun 2022 12:15:39 +0200 Subject: Fix T98604: FBX import does not handle some framerate codes. Add missing values to the `FBX_FRAMERATES` data, including those that Blender does not really support (the NTSC 'drop frames' variants, better to have them mapped to regular NTSC framerate than completely ignored). --- io_scene_fbx/__init__.py | 2 +- io_scene_fbx/fbx_utils.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index 02d135b1..f7415a38 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -3,7 +3,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier", - "version": (4, 36, 0), + "version": (4, 36, 1), "blender": (3, 2, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py index 35fdede7..41c63ef8 100644 --- a/io_scene_fbx/fbx_utils.py +++ b/io_scene_fbx/fbx_utils.py @@ -112,21 +112,28 @@ RIGHT_HAND_AXES = { } +# NOTE: Not fully in enum value order, since when exporting the first entry matching the framerate value is used +# (e.g. better have NTSC fullframe than NTSC drop frame for 29.97 framerate). FBX_FRAMERATES = ( + #(-1.0, 0), # Default framerate. (-1.0, 14), # Custom framerate. (120.0, 1), (100.0, 2), (60.0, 3), (50.0, 4), (48.0, 5), - (30.0, 6), # BW NTSC. - (30.0 / 1.001, 9), # Color NTSC. + (30.0, 6), # BW NTSC, full frame. + (30.0, 7), # Drop frame. + (30.0 / 1.001, 9), # Color NTSC, full frame. + (30.0 / 1.001, 8), # Color NTSC, drop frame. (25.0, 10), (24.0, 11), + #(1.0, 12), # 1000 milli/s (use for date time?). (24.0 / 1.001, 13), (96.0, 15), (72.0, 16), (60.0 / 1.001, 17), + (120.0 / 1.001, 18), ) -- cgit v1.2.3 From 514aca8ac9cf485a27676fca5441a6445aef498b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 13 Jun 2022 12:55:09 +0200 Subject: Fix T98345: Import von FBX didn't work. Highly suspect the source FBX file to be broken, but investigating a 20MB binary FBX file is not really an option right now, so cannot be 100% sure. This can only be realistically investigated if we get a much smaller reproducible case. In the mean while, add similar check about indices validity for source FBX data as we already have for destination Blender data arrays. This allows to keep importing instead of 'crshing' the import process at least. --- io_scene_fbx/__init__.py | 2 +- io_scene_fbx/import_fbx.py | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py index f7415a38..1b7e646d 100644 --- a/io_scene_fbx/__init__.py +++ b/io_scene_fbx/__init__.py @@ -3,7 +3,7 @@ bl_info = { "name": "FBX format", "author": "Campbell Barton, Bastien Montagne, Jens Restemeier", - "version": (4, 36, 1), + "version": (4, 36, 2), "blender": (3, 2, 0), "location": "File > Import-Export", "description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions", diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index 5fabec24..90f0c016 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -778,16 +778,22 @@ def blen_read_geom_layerinfo(fbx_layer): def blen_read_geom_array_setattr(generator, blen_data, blen_attr, fbx_data, stride, item_size, descr, xform): """Generic fbx_layer to blen_data setter, generator is expected to yield tuples (ble_idx, fbx_idx).""" - max_idx = len(blen_data) - 1 + max_blen_idx = len(blen_data) - 1 + max_fbx_idx = len(fbx_data) - 1 print_error = True def check_skip(blen_idx, fbx_idx): nonlocal print_error if fbx_idx < 0: # Negative values mean 'skip'. return True - if blen_idx > max_idx: + if blen_idx > max_blen_idx: if print_error: - print("ERROR: too much data in this layer, compared to elements in mesh, skipping!") + print("ERROR: too much data in this Blender layer, compared to elements in mesh, skipping!") + print_error = False + return True + if fbx_idx + item_size - 1 > max_fbx_idx: + if print_error: + print("ERROR: not enough data in this FBX layer, skipping!") print_error = False return True return False -- cgit v1.2.3 From e72fe78e1d08eb8c5e9af124068edead7f896557 Mon Sep 17 00:00:00 2001 From: Martin Felke Date: Mon, 13 Jun 2022 22:58:18 +0200 Subject: Fix T98840: Recursion Error with Development - Edit Operator Addon In the prior versions of this addon I had to generate a list of builtin and standard python modules, which need to be excluded in the walk function. This function is being called recursively over all blender py modules and addon modules. Certain builtin or standard modules of python seem to have some recursion in their module structure, which needs to be avoided. Since Python 3.10, you can use 'sys.stdlib_module_names' for a basic list. Possibly the old method generated an incomplete list. --- development_edit_operator.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/development_edit_operator.py b/development_edit_operator.py index e51df36e..0936f57b 100644 --- a/development_edit_operator.py +++ b/development_edit_operator.py @@ -1,11 +1,27 @@ -# SPDX-License-Identifier: GPL-2.0-or-later +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### bl_info = { "name": "Edit Operator Source", "author": "scorpion81", - "version": (1, 2, 2), - "blender": (2, 80, 0), + "version": (1, 2, 3), + "blender": (3, 2, 0), "location": "Text Editor > Sidebar > Edit Operator", "description": "Opens source file of chosen operator or call locations, if source not available", "warning": "", @@ -30,18 +46,6 @@ from bpy.props import ( IntProperty ) -def stdlib_excludes(): - #need a handy list of modules to avoid walking into - import distutils.sysconfig as sysconfig - excludes = [] - std_lib = sysconfig.get_python_lib(standard_lib=True) - for top, dirs, files in os.walk(std_lib): - for nm in files: - if nm != '__init__.py' and nm[-3:] == '.py': - excludes.append(os.path.join(top, nm)[len(std_lib)+1:-3].replace('\\','.')) - - return excludes - def make_loc(prefix, c): #too long and not helpful... omitting for now space = "" @@ -219,8 +223,10 @@ class TEXT_OT_EditOperator(Operator): def show_calls(self, context): import bl_ui import addon_utils + import sys - exclude = stdlib_excludes() + exclude = [] + exclude.extend(sys.stdlib_module_names) exclude.append("bpy") exclude.append("sys") -- cgit v1.2.3 From 4ca8ca981feda3f7a4bd8bb7c3912327c8f53fcf Mon Sep 17 00:00:00 2001 From: Martin Felke Date: Mon, 13 Jun 2022 23:03:01 +0200 Subject: fix accidentally re-added license header The remote version didnt have the GPL Header in its full form before. So restoring this part to the original state. --- development_edit_operator.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/development_edit_operator.py b/development_edit_operator.py index 0936f57b..bd406e49 100644 --- a/development_edit_operator.py +++ b/development_edit_operator.py @@ -1,20 +1,4 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### +# SPDX-License-Identifier: GPL-2.0-or-later bl_info = { -- cgit v1.2.3 From 470d0257c40ba2ff7dcd34800a771cd3c2229c67 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 14 Jun 2022 03:45:22 +0200 Subject: AnimAll: add attribute animation Vertex colors have been replaced by a more generic attribute system, so we need to support that. This allows animating not only color attributes, but also other types. Not sure that's very useful as most attributes can't be manually edited as far as I understand, but it *is* now possible! --- animation_animall.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/animation_animall.py b/animation_animall.py index 309141a9..fe99019c 100644 --- a/animation_animall.py +++ b/animation_animall.py @@ -3,8 +3,8 @@ bl_info = { "name": "AnimAll", "author": "Daniel Salazar ", - "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: -- cgit v1.2.3 From 634f0c8c91879aa98cd485526b3742a86d348326 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 14 Jun 2022 18:39:09 +0200 Subject: AnimAll: remove vertex colors Vertex color access through `Mesh.vertex_colors` is deprecated and will be removed eventually. https://wiki.blender.org/wiki/Reference/Release_Notes/3.2/Python_API#Deprecation It is already not entirely functional for AnimAll's workflow: if there are multiple vertex color layers, the active one cannot be selected because the interface is no longer exposed. This results in the user being unable to select which layer they want to animate. Besides, all functionality is covered by the more generic attributes system. An operator is provided to upgrade animation curves still using the old system. --- animation_animall.py | 62 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/animation_animall.py b/animation_animall.py index fe99019c..fdbeff8d 100644 --- a/animation_animall.py +++ b/animation_animall.py @@ -3,7 +3,7 @@ bl_info = { "name": "AnimAll", "author": "Daniel Salazar ", - "version": (0, 9, 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", @@ -62,11 +62,6 @@ 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", @@ -172,10 +167,22 @@ 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_vgroups") - row = col.row() 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") @@ -338,12 +345,6 @@ 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, 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 @@ -469,12 +470,6 @@ 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 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 @@ -599,6 +594,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 @@ -651,6 +669,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) @@ -662,6 +681,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__": -- cgit v1.2.3 From 70f5863c3092c15329aa15c44b5c04cb9ba0557f Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Thu, 16 Jun 2022 11:25:27 +0200 Subject: AnimAll: remove accidentally duplicated block --- animation_animall.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/animation_animall.py b/animation_animall.py index fdbeff8d..a7d76f53 100644 --- a/animation_animall.py +++ b/animation_animall.py @@ -490,25 +490,6 @@ class ANIM_OT_delete_keyframe_animall(Operator): 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: if obj.active_shape_key: -- cgit v1.2.3 From aa353e127c2be0a31e10f8b3621fc418bcf6d6ef Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Fri, 17 Jun 2022 07:41:02 +0200 Subject: glTF exporter: Regression: Fix T98912 - export driven SK when mesh parented to bone --- io_scene_gltf2/__init__.py | 2 +- io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index fd3d2d56..ce48f293 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -4,7 +4,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (3, 3, 4), + "version": (3, 3, 5), 'blender': (3, 3, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py index 4e77f60e..b0e538c8 100644 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py @@ -12,7 +12,12 @@ def get_sk_drivers(blender_armature_uuid, export_settings): drivers = [] - for child_uuid in export_settings['vtree'].nodes[blender_armature_uuid].children: + # Take into account skinned mesh, and mesh parented to a bone of the armature + children_list = export_settings['vtree'].nodes[blender_armature_uuid].children + for bone in export_settings['vtree'].get_all_bones(blender_armature_uuid): + children_list.extend(export_settings['vtree'].nodes[bone].children) + + for child_uuid in children_list: if export_settings['vtree'].nodes[child_uuid].blender_type == "BONE": continue -- cgit v1.2.3