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