import bpy def get_collection_parents(col, root=None, cols=None): """Return all direct collection parents Args: col (bpy.types.Collection): collection to get parents from root (bpy.types.Collection, optional): collection to search in (recursive) instead of the scene collection. Defaults to None. cols (_type_, optional): for recursivity, store the parent collections. Defaults to None. Returns: list[bpy.types.Collection]: a list of direct parents """ if cols is None: cols = [] if root is None: root = bpy.context.scene.collection for sub in root.children: if sub == col: cols.append(root) if len(sub.children): cols = get_collection_parents(col, root=sub, cols=cols) return cols def get_view_3d_override(): windows = bpy.context.window_manager.windows areas = [a for w in windows for a in w.screen.areas if a.type == "VIEW_3D"] if not areas: print("No view 3d found") return view_3d = None for area in areas: if area.spaces.active.camera: view_3d = area if not view_3d: view_3d = max(areas, key=lambda x: x.width) return {"area": view_3d, "region": view_3d.regions[-1]} def get_mat(ob): for sl in ob.material_slots: if sl.material: return sl.material def link_mat_to_object(ob): for sl in ob.material_slots: m = sl.material sl.link = "OBJECT" sl.material = m def eval_attr(ob, name): resolved = ob for o in name.split("."): resolved = getattr(resolved, o) return resolved def flip_name(name): if not name: return if name.startswith("[") and name.endswith("]"): # It's a custom property flipped_name = bpy.utils.flip_name(name[:-2][2:]) return f'["{flipped_name}"]' else: return bpy.utils.flip_name(name) def split_path(path): try: bone_name = path.split('["')[1].split('"]')[0] except Exception: bone_name = None try: prop_name = path.split('["')[2].split('"]')[0] except Exception: prop_name = None return bone_name, prop_name def hide_layers(args): """ """ ob = bpy.context.object layers = [] for bone in [b for b in ob.pose.bones if b.bone.select]: for i, l in enumerate(bone.bone.layers): if l and i not in layers: layers.append(i) for i in layers: ob.data.layers[i] = not ob.data.layers[i] def select_layer(args): ob = bpy.context.object layers = [] for bone in [b for b in ob.pose.bones if b.bone.select]: bone_layers = [i for i, l in enumerate(bone.bone.layers) if l] for l in bone_layers: if l not in layers: layers.append(l) for bone in ob.pose.bones: bone_layers = [i for i, l in enumerate(bone.bone.layers) if l] if len(set(bone_layers).intersection(layers)): bone.bone.select = True def hide_bones(args): ob = bpy.context.object selected_bone = [b for b in ob.pose.bones if b.bone.select] hide = [b.bone.hide for b in selected_bone if not b.bone.hide] visibility = True if len(hide) else False for bone in selected_bone: bone.bone.hide = visibility def select_all(args): ob = bpy.context.object shapes = ob.data.rig_picker["shapes"] bones = [s["bone"] for s in shapes if s["shape_type"] == "BONE"] for bone_name in bones: bone = ob.pose.bones.get(bone_name) if bone: bone.bone.select = True