update bg images operator

master
pullusb 2023-10-04 14:15:34 +02:00
parent 3bd39cbed4
commit 7cfcae25e5
6 changed files with 105 additions and 7 deletions

View File

@ -4,7 +4,7 @@ bl_info = {
"name": "Background plane manager", "name": "Background plane manager",
"description": "Manage the background image planes and grease pencil object relative to a camera", "description": "Manage the background image planes and grease pencil object relative to a camera",
"author": "Samuel Bernou", "author": "Samuel Bernou",
"version": (0, 4, 3), "version": (0, 5, 0),
"blender": (3, 5, 0), "blender": (3, 5, 0),
"location": "View3D", "location": "View3D",
"warning": "", "warning": "",
@ -60,6 +60,7 @@ except Exception:
# Override this enum if there is an environement variable in project # Override this enum if there is an environement variable in project
modules = ( modules = (
import_planes,
operators, operators,
export_psd_layers, export_psd_layers,
preferences, preferences,

View File

@ -321,6 +321,12 @@ def set_collection(ob, collection, unlink=True) :
return col 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 placeholder_name(name='', context=None) -> str:
# def increment(match): # def increment(match):

View File

@ -1,3 +1,4 @@
import bpy
from . import operators from . import operators
modules = ( modules = (
@ -6,8 +7,8 @@ modules = (
def register(): def register():
for module in modules: for module in modules:
bpy.utils.register_class(module) module.register()
def unregister(): def unregister():
for module in reversed(modules): for module in reversed(modules):
bpy.utils.unregister_class(module) module.unregister()

View File

@ -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): class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper):
bl_idname = "bpm.import_bg_images" bl_idname = "bpm.import_bg_images"
bl_label = "Import Background 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), # ('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): def execute(self, context):
org_image_size = None org_image_size = None
scn = context.scene scn = context.scene
@ -127,4 +129,4 @@ def register():
def unregister(): def unregister():
for cls in reversed(classes): for cls in reversed(classes):
bpy.utils.unregister_class(cls) bpy.utils.unregister_class(cls)

View File

@ -1,6 +1,7 @@
from pathlib import Path from pathlib import Path
import bpy import bpy
import re
from bpy.types import Operator from bpy.types import Operator
from mathutils import Vector from mathutils import Vector
from os.path import abspath from os.path import abspath
@ -299,6 +300,91 @@ class BPM_OT_reload(Operator):
return{'CANCELLED'} return{'CANCELLED'}
return {"FINISHED"} 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=( classes=(
# BPM_OT_change_background_type, # BPM_OT_change_background_type,
BPM_OT_select_swap, BPM_OT_select_swap,
@ -307,7 +393,8 @@ BPM_OT_select_all,
BPM_OT_reload, BPM_OT_reload,
BPM_OT_open_bg_folder, BPM_OT_open_bg_folder,
BPM_OT_set_distance, BPM_OT_set_distance,
BPM_OT_move_plane BPM_OT_move_plane,
BPM_OT_update_bg_images,
) )
def register(): def register():

View File

@ -311,6 +311,7 @@ class BPM_more_option(Menu):
layout.operator("bpm.reload_list", text="Refresh", icon="FILE_REFRESH") layout.operator("bpm.reload_list", text="Refresh", icon="FILE_REFRESH")
layout.operator("bpm.open_bg_folder", icon="FILE_FOLDER") layout.operator("bpm.open_bg_folder", icon="FILE_FOLDER")
layout.operator("bpm.import_bg_images", text="Import Planes", icon="IMPORT") 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.operator("bpm.convert_planes", text="Convert Planes", icon="OUTLINER_OB_IMAGE")
layout.separator() layout.separator()
layout.prop(context.scene.bg_props, 'show_distance', icon='DRIVER_DISTANCE') layout.prop(context.scene.bg_props, 'show_distance', icon='DRIVER_DISTANCE')