Merge branch 'master' into xr-dev

This commit is contained in:
Peter Kim 2022-06-17 17:28:06 +09:00
commit ec84e32945
10 changed files with 157 additions and 51 deletions

View File

@ -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':

View File

@ -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__":

View File

@ -4,8 +4,8 @@
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 +30,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 +207,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")

View File

@ -3,7 +3,7 @@
bl_info = {
"name": "FBX format",
"author": "Campbell Barton, Bastien Montagne, Jens Restemeier",
"version": (4, 36, 0),
"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",

View File

@ -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),
)

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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",
@ -3747,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):
@ -3761,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
@ -3773,11 +3777,16 @@ 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':
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):
@ -3796,6 +3805,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

View File

@ -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):