165 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
						|
 | 
						|
import bpy
 | 
						|
import re
 | 
						|
# import bpy_extras
 | 
						|
# from bpy_extras.io_utils import ImportHelper
 | 
						|
from pathlib import Path
 | 
						|
from bpy.types import Operator
 | 
						|
from .. import core
 | 
						|
from .. constants import BGCOL, MODULE_DIR
 | 
						|
 | 
						|
## Plane conversion between multiple types: GP plane / image plane / empty references
 | 
						|
 | 
						|
def convert_background_image(ob, target = 'GPENCIL'):
 | 
						|
    '''Target in ['GPENCIL', 'EMPTY', 'MESH']'''
 | 
						|
 | 
						|
    if target == ob.type:
 | 
						|
        print('WARNING', f'{ob.name} Already of type {target}')
 | 
						|
        return
 | 
						|
 | 
						|
    scn = bpy.context.scene
 | 
						|
    cam = scn.objects.get('bg_cam')
 | 
						|
    if not cam:
 | 
						|
        cam = ob.parent
 | 
						|
    if not cam: 
 | 
						|
        cam = scn.camera
 | 
						|
    if not cam:
 | 
						|
        print('No "bg_cam", no parent, source object is not parented !')
 | 
						|
        return
 | 
						|
 | 
						|
    # Get info from Source
 | 
						|
    img_infos = core.get_image_infos_from_object(ob)
 | 
						|
    if not img_infos:
 | 
						|
        print(f'No could not retrieve image source from {ob}')
 | 
						|
        return
 | 
						|
 | 
						|
    image_data, opacity = img_infos
 | 
						|
 | 
						|
 | 
						|
    ### Create new plane type
 | 
						|
 | 
						|
    ## RENAME to avoid conflict (always keep same name for list scan ?)
 | 
						|
    ## rename source temporarily
 | 
						|
    ## write type in name ?
 | 
						|
    ## name only holder (if there is a holder)
 | 
						|
 | 
						|
    ob.name = f'{ob.name}_temp'
 | 
						|
    
 | 
						|
    ## TODO: ensure image filepath is ok ?
 | 
						|
    
 | 
						|
    suffix = ''
 | 
						|
    if target == 'GPENCIL':
 | 
						|
        ## Create GP plane from Texture source
 | 
						|
        new = core.import_image_as_gp_reference(
 | 
						|
        image_data,
 | 
						|
        pack_image=False,
 | 
						|
        )
 | 
						|
        suffix = '_texgp'
 | 
						|
 | 
						|
    if target == 'MESH':
 | 
						|
        ## HARDCODED text blend path:
 | 
						|
        # blend = '/s/blender/blender-2.9_scripts/addons/bg_plane_manager/texture_plane.blend'
 | 
						|
        blend = str(MODULE_DIR / 'texture_plane.blend')
 | 
						|
        node_group = core.link_nodegroup(blend, 'texture_plane', link=False)
 | 
						|
        new = core.create_image_plane(image_data, node_group)
 | 
						|
        suffix = '_texplane'
 | 
						|
    
 | 
						|
    if target == 'EMPTY':
 | 
						|
        new = core.create_empty_image(image_data)
 | 
						|
        suffix = '_texempty'
 | 
						|
 | 
						|
 | 
						|
    # Strip after '.' or get original name ?
 | 
						|
    print('source name: ', new.name)
 | 
						|
    new.name = core.clean_image_name(image_data.name) + suffix
 | 
						|
    print('final name:', new.name)
 | 
						|
    new['is_background'] = True
 | 
						|
 | 
						|
    ## Without holder
 | 
						|
    ## Transfer attributes
 | 
						|
    # core.create_plane_driver(new, cam)
 | 
						|
    # new.parent = cam
 | 
						|
 | 
						|
    # new['distance'] = ob['distance']
 | 
						|
    # new['scale'] = ob['scale']
 | 
						|
 | 
						|
 | 
						|
    # new.lock_location = ob.lock_location # lock only X,Y ?
 | 
						|
    # new.hide_select = ob.hide_select
 | 
						|
    
 | 
						|
    # new.rotation_euler = ob.rotation_euler
 | 
						|
 | 
						|
    ## With holder
 | 
						|
    new.parent = ob.parent
 | 
						|
 | 
						|
 | 
						|
    ## Loc/scale overrided by driver
 | 
						|
    # new.location = ob.location
 | 
						|
    # new.scale = ob.scale
 | 
						|
 | 
						|
    ## Transfer current transparency
 | 
						|
 | 
						|
    # Destination
 | 
						|
    core.set_opacity(new, opacity)
 | 
						|
 | 
						|
    ## Set in collection 
 | 
						|
    if not len(ob.users_collection):
 | 
						|
        core.set_collection(new, BGCOL)
 | 
						|
    else:
 | 
						|
        core.set_collection(new, ob.users_collection[0].name)
 | 
						|
 | 
						|
    ## Remove old object
 | 
						|
    bpy.data.objects.remove(ob)
 | 
						|
 | 
						|
    return new
 | 
						|
 | 
						|
 | 
						|
class BPM_OT_convert_planes(Operator):
 | 
						|
    bl_idname = "bpm.convert_planes"
 | 
						|
    bl_label = "Convert Planes"
 | 
						|
    bl_description = "Convert as plane all images inside a folder"
 | 
						|
    bl_options = {"REGISTER"} # , "UNDO"
 | 
						|
 | 
						|
    target_type : bpy.props.EnumProperty(
 | 
						|
        name="Convert To", description="", default='GPENCIL', options={'ANIMATABLE'},
 | 
						|
        items=(
 | 
						|
            ('GPENCIL', 'Gpencil Object', 'Convert bg planes to gpencil objects', 0),
 | 
						|
            ('EMPTY', 'Empty Reference', 'Convert bg planes to empty objects', 1),   
 | 
						|
            ('MESH', 'Texture Plane', 'Convert bg planes to mesh objects', 2),   
 | 
						|
            ))
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_props_dialog(self, width=250)
 | 
						|
        # return self.execute(context)
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        print('BPM_OT_convert_planes')
 | 
						|
        holder_list = core.scan_backgrounds(all_bg=True)
 | 
						|
        if not holder_list:
 | 
						|
            self.report({'ERROR'}, 'No Background found to convert, Structure must have a parent holder')
 | 
						|
            return {'CANCELLED'}
 | 
						|
        for holder in holder_list:
 | 
						|
            if not holder.children:
 | 
						|
                print(f'{holder.name} has not child')
 | 
						|
                continue
 | 
						|
            ob = holder.children[0] # take first child FIXME: what if multiple childrens ?
 | 
						|
            new_bg = convert_background_image(ob, target=self.target_type)
 | 
						|
 | 
						|
 | 
						|
        # if isinstance(new_bg, str):
 | 
						|
        #     self.report({'ERROR'}, new_bg)
 | 
						|
        return {"FINISHED"}
 | 
						|
 | 
						|
classes=(
 | 
						|
BPM_OT_convert_planes,
 | 
						|
)
 | 
						|
 | 
						|
def register():
 | 
						|
    for cls in classes:
 | 
						|
        bpy.utils.register_class(cls)
 | 
						|
 | 
						|
def unregister():
 | 
						|
    for cls in reversed(classes):
 | 
						|
        bpy.utils.unregister_class(cls)
 |