From 7cfcae25e56c4c5f9f26a1bc695518463539df11 Mon Sep 17 00:00:00 2001 From: pullusb Date: Wed, 4 Oct 2023 14:15:34 +0200 Subject: [PATCH] update bg images operator --- __init__.py | 3 +- core.py | 6 +++ import_planes/__init__.py | 5 ++- import_planes/operators.py | 8 ++-- operators/manage_planes.py | 89 +++++++++++++++++++++++++++++++++++++- ui/ui_list.py | 1 + 6 files changed, 105 insertions(+), 7 deletions(-) diff --git a/__init__.py b/__init__.py index 19acdb7..d0d3a60 100644 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,7 @@ bl_info = { "name": "Background plane manager", "description": "Manage the background image planes and grease pencil object relative to a camera", "author": "Samuel Bernou", - "version": (0, 4, 3), + "version": (0, 5, 0), "blender": (3, 5, 0), "location": "View3D", "warning": "", @@ -60,6 +60,7 @@ except Exception: # Override this enum if there is an environement variable in project modules = ( + import_planes, operators, export_psd_layers, preferences, diff --git a/core.py b/core.py index 6f1d8dd..074b2a4 100644 --- a/core.py +++ b/core.py @@ -321,6 +321,12 @@ def set_collection(ob, collection, unlink=True) : return col +def get_parent_collection(obj): + '''return first parent collection found''' + for col in bpy.context.scene.collection.children_recursive: + if obj.name in col.objects: + return col + def placeholder_name(name='', context=None) -> str: # def increment(match): diff --git a/import_planes/__init__.py b/import_planes/__init__.py index 9e59432..06a3138 100644 --- a/import_planes/__init__.py +++ b/import_planes/__init__.py @@ -1,3 +1,4 @@ +import bpy from . import operators modules = ( @@ -6,8 +7,8 @@ modules = ( def register(): for module in modules: - bpy.utils.register_class(module) + module.register() def unregister(): for module in reversed(modules): - bpy.utils.unregister_class(module) \ No newline at end of file + module.unregister() diff --git a/import_planes/operators.py b/import_planes/operators.py index ad63d94..7f0d600 100644 --- a/import_planes/operators.py +++ b/import_planes/operators.py @@ -22,8 +22,6 @@ from . core import import_planes, get_json_infos, reload_bg_list - - class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper): bl_idname = "bpm.import_bg_images" bl_label = "Import Background images" @@ -66,6 +64,10 @@ class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper): # ('PURGE', 'Purge', 'When object exists, fully delete it before linking, even associated collection and holder', 2), )) + # import_psd_as_image : BoolProperty(name='Import PSD as Image (no content extraction)', + # description='Direct import of the PSD, otherwise extract using psd_tools' + # default=False) + def execute(self, context): org_image_size = None scn = context.scene @@ -127,4 +129,4 @@ def register(): def unregister(): for cls in reversed(classes): - bpy.utils.unregister_class(cls) \ No newline at end of file + bpy.utils.unregister_class(cls) diff --git a/operators/manage_planes.py b/operators/manage_planes.py index 1415248..eeeec0b 100644 --- a/operators/manage_planes.py +++ b/operators/manage_planes.py @@ -1,6 +1,7 @@ from pathlib import Path import bpy +import re from bpy.types import Operator from mathutils import Vector from os.path import abspath @@ -299,6 +300,91 @@ class BPM_OT_reload(Operator): return{'CANCELLED'} return {"FINISHED"} +class BPM_OT_update_bg_images(Operator): + bl_idname = "bpm.update_bg_images" + bl_label = "Update Bg Planes Images" + bl_description = "Update the loaded images if there are newer version\ + \n(source files name needs to end with a version number)" + bl_options = {"REGISTER"} # , "UNDO" + + @classmethod + def poll(cls, context): + return True + + def execute(self, context): + print('Updating barckground images:') + + ct = 0 + right_num = re.compile(r'(\d+)(?!.*\d)') + for item in context.scene.bg_props.planes: + if item.type != 'bg': + continue + holder = item.plane + if not holder: + continue + for bg_obj in holder.children: + image = core.get_image(bg_obj) + # print(f'holder:{holder.name} > obj({bg_obj.type}):{bg_obj.name} > img:{image.name} > {image.filepath}') + + img = Path(bpy.path.abspath(image.filepath)) + + if not re.search(r'\d+$', img.stem): + print(f'SKIP: object "{bg_obj.name}" > image "{image.name}" does not end with version') + img_folder = img.parent + + # List in folder : only file versionned, with same suffix and same basename + images_list = [i for i in img_folder.iterdir() if i.is_file()\ + and re.search(r'\d+$', i.stem)\ + and i.suffix == img.suffix\ + and right_num.sub('', img.stem) == right_num.sub('', i.stem)] + + ## images_list should neveer be empty (source img should be listed) + # for i in images_list: + # print(i.stem) + + images_list.sort() + last = images_list[-1] + if last == img: + print(f'Already up to date: {image.name}') + continue + + ## Update with last number + print(f'Update: {img.name} >> {last.name}') + + ## keep current fielpath head (to not affect relative/absolute) + new_path = Path(image.filepath).parent / last.name + print('New path: ', new_path) + + # Update image filepath and name + image.filepath = str(new_path) + image.name = new_path.name + + ### Propagate new names + + ## Rename collection + parent_col = core.get_parent_collection(holder) + parent_col.name = new_path.stem + + # Rename holder keeping prefix + holder.name = holder.data.name = f'BG_{new_path.stem}' + + ## Rename object keeping type suffix + if bg_obj.name.endswith(('_texgp', '_texplane', '_texempty')): + type_suffix = f"_tex{bg_obj.name.split('_tex')[-1]}" + else: + type_suffix = '' + + bg_obj.name = bg_obj.data.name = f'{new_path.stem}{type_suffix}' + + ct += 1 + + if ct: + self.report({'INFO'}, f'Updated {ct} background images') + else: + self.report({'INFO'}, 'All background images are up to date') + + return {"FINISHED"} + classes=( # BPM_OT_change_background_type, BPM_OT_select_swap, @@ -307,7 +393,8 @@ BPM_OT_select_all, BPM_OT_reload, BPM_OT_open_bg_folder, BPM_OT_set_distance, -BPM_OT_move_plane +BPM_OT_move_plane, +BPM_OT_update_bg_images, ) def register(): diff --git a/ui/ui_list.py b/ui/ui_list.py index 21a2bb0..e268a54 100644 --- a/ui/ui_list.py +++ b/ui/ui_list.py @@ -311,6 +311,7 @@ class BPM_more_option(Menu): layout.operator("bpm.reload_list", text="Refresh", icon="FILE_REFRESH") layout.operator("bpm.open_bg_folder", icon="FILE_FOLDER") layout.operator("bpm.import_bg_images", text="Import Planes", icon="IMPORT") + layout.operator("bpm.update_bg_images", text="Update Versions", icon="SEQ_SPLITVIEW") layout.operator("bpm.convert_planes", text="Convert Planes", icon="OUTLINER_OB_IMAGE") layout.separator() layout.prop(context.scene.bg_props, 'show_distance', icon='DRIVER_DISTANCE')