refacto to use import_planes as a functions

master
ChristopheSeux 2023-09-28 12:54:37 +02:00
parent ba5084e458
commit 11029606df
12 changed files with 344 additions and 308 deletions

View File

@ -16,11 +16,12 @@ import bpy
from pathlib import Path
from . import operators
from . import import_planes
from . import export_psd_layers
from . import ui
from . import preferences
from . import fn
from . import core
#from . file_utils import install_module
#install_module('psd_tools', 'psd-tools')
@ -69,7 +70,7 @@ def register():
for m in modules:
m.register()
preferences.ui_in_sidebar_update(fn.get_addon_prefs(), bpy.context)
preferences.ui_in_sidebar_update(core.get_addon_prefs(), bpy.context)
def unregister():
for m in reversed(modules):

View File

@ -453,14 +453,12 @@ def create_gpencil_reference(
return gps_new
def import_image_as_gp_reference(
context: bpy.types.Context,
image,
pack_image: bool = False,
):
"""
Import image from `image` as a textured rectangle in the given
grease pencil object.
:param context: The active context.
:param image: The image filepath or image datablock
:param pack_image: Whether to pack the image into the Blender file.
"""
@ -468,7 +466,7 @@ def import_image_as_gp_reference(
if not image:
return
scene = context.scene
scene = bpy.context.scene
if not isinstance(image, bpy.types.Image):
image = bpy.data.images.load(str(image), check_existing=True)
@ -807,3 +805,4 @@ def coord_distance_from_cam(coord, context=None, camera=None):
if not camera:
return
return (coord - camera.matrix_world.to_translation()).length

View File

@ -7,7 +7,7 @@ import json
#import psd_tools
from pathlib import Path
from time import time
from . import fn
from . import core
from . file_utils import install_module
@ -83,7 +83,7 @@ def export_psd(psd_file, output=None, scale=0.5):
l.visible = True
name = layer.name
norm_name = fn.norm_str(name, padding=2) # Gadget normstr
norm_name = core.norm_str(name, padding=2) # Gadget normstr
print('name: ', name)
png_output = (output/norm_name).with_suffix('.png')

13
import_planes/__init__.py Normal file
View File

@ -0,0 +1,13 @@
from . import operators
modules = (
operators,
)
def register():
for module in modules:
bpy.utils.register_class(module)
def unregister():
for module in reversed(modules):
bpy.utils.unregister_class(module)

158
import_planes/core.py Normal file
View File

@ -0,0 +1,158 @@
import bpy
import json
from pathlib import Path
import os
import re
import time
from pathlib import Path
from mathutils import Vector, geometry
from pprint import pprint as pp
from ..constants import PREFIX, BGCOL, INIT_POS
from ..core import (create_cam, set_collection, get_image_infos_from_object, get_col,
import_image_as_gp_reference, create_image_plane, set_collection, get_image,
create_empty_image, create_plane_holder, create_plane_driver, reload_bg_list)
def get_json_infos(json_path) -> tuple((list, tuple)):
'''return a tuple with (image paths list, [x, y] original psd resolution'''
import json
setup_json_path = Path(json_path)
setup_json = json.loads(setup_json_path.read_text())
# psd = Path(setup_json['psd']) # path to psd
# image_size = setup_json['image_size'] # image size (reduced)
# png_dir = Path(setup_json['png_dir']) # path to png directory
layers = setup_json['layers'] # dic : name, lbbox, bbox, index, path
org_image_size = setup_json['org_image_size'] # original PSD dimensions
img_list = [Path(l['path']) for l in layers] # (png_dir /l['name']).with_suffix('.png')
return img_list, org_image_size
def setup_bg_camera(image_size, scene=None, cam_type=None):
'''Create background camera from scene active camera according to background image resolution
image_size ::
cam_type :: wether the BG camera should be set to perspective or orthographic
'''
scn = scene or bpy.context.scene
movie_resolution = scn.render.resolution_x, scn.render.resolution_y
anim_cam = scn.camera
anim_cam_scale = 6 # anim_cam.data.ortho_scale
anim_cam_focale = 50 # anim_cam.data.lens
cam_type = cam_type or anim_cam.data.type
## scale up plane scale and bg_cam ortho_scale according to film res
bg_factor = (anim_cam_scale * image_size[0]) / movie_resolution[0]
#print(f'({anim_cam_scale} * {image_size[0]}) / {movie_resolution[0]} = {bg_factor}')
## scale down the focal according to film res
bg_focale = (anim_cam_focale * movie_resolution[0]) / image_size[0]
#print(f'({anim_cam_focale} * {movie_resolution[0]}) / {image_size[0]} = {bg_focale}')
bg_cam = scn.objects.get('bg_cam')
if not bg_cam:
bg_cam = create_cam(name='bg_cam', type=cam_type, size=bg_factor, focale=bg_focale)
bg_cam['resolution'] = image_size
bg_cam.matrix_world = anim_cam.matrix_world
bg_cam.hide_select = True
bg_cam.lock_location = bg_cam.lock_rotation = bg_cam.lock_scale = [True]*3
set_collection(bg_cam, 'Camera')
set_collection(anim_cam, 'Camera')
return bg_cam
def import_planes(images, import_type='GPENCIL', mode='REPLACE', image_size=None):
scn = bpy.context.scene
existing_backgrounds = [(o, *img_info) for o in scn.objects \
if o.get('is_background') and (img_info := get_image_infos_from_object(o)) and o.get('is_background') and o.parent]
existing_backgrounds.sort(key=lambda x: x[0].parent.location.z, reverse=True) # sort by parent (holder) location Z
far_plane = INIT_POS
if existing_backgrounds:
far_plane = existing_backgrounds[-1][0].parent.location.z
## Ensure bg_cam setup (option to use active camera ?)
bg_cam = scn.objects.get('bg_cam')
if not bg_cam:
if not image_size:
## Get image size from first file
img = bpy.data.images.load(str(images[0]), check_existing=True)
image_size = (img.size[0], img.size[1])
bg_cam = setup_bg_camera(image_size)
## Ensure Background collection
backgrounds = get_col(BGCOL) # Create if needed
for image_path in images:
image_path = Path(image_path)
print(f'Importing {image_path.name}')
current_holder = None
file_stem = image_path.stem
# current_bg = next((o for o if o.parent and get_image_infos_from_object(o)), None)
current_bg = next((o for o in existing_backgrounds if Path(o[1].filepath) == image_path), None)
if current_bg:
current_holder = current_bg.parent
# TODO store opacity or delete existing objects only after loop
if current_bg and mode == 'SKIP':
print(f' - SKIP: existing {current_bg.name}')
continue
if current_bg and mode == 'REPLACE':
print(f' - DEL: existing {current_bg.name}')
bpy.data.objects.remove(current_bg)
# Import image
if import_type == 'GPENCIL':
bg_img = import_image_as_gp_reference(
image=str(image_path),
pack_image=False,
)
elif import_type == 'MESH':
bg_img = create_image_plane(image_path)
elif import_type == 'EMPTY':
bg_img = create_empty_image(image_path)
bg_img.name = file_stem + '_texgp'
bg_img.hide_select = True
if current_holder:
bg_img.parent = current_holder
set_collection(bg_img, current_holder.users_collection[0].name)
continue
# img, opacity = get_image_infos_from_object(bg_img)
print('bg_img: ', bg_img)
img = get_image(bg_img)
# bg_name = clean_image_name(img.name)
file_stem = file_stem
# Get create collection from image clean name
bg_col = get_col(file_stem, parent=backgrounds)
## Set in collection
bg_col.objects.link(bg_img)
print('img: ', img.name, bg_img.name, bg_img.users_collection)
## create the holder, parent to camera, set driver and set collection. Could also pass 'fp'
holder = create_plane_holder(img, name=PREFIX + file_stem, parent=bg_cam, link_in_col=bg_col)
print('holder: ', holder.name)
create_plane_driver(holder, bg_cam, distance=far_plane)
bg_img.parent = holder
far_plane += 2
reload_bg_list(scene=scn)

130
import_planes/operators.py Normal file
View File

@ -0,0 +1,130 @@
# SPDX-License-Identifier: GPL-3.0-or-later
## Standalone based on SPA code
## Code from create_gp_texture_ref.py (Copyright (C) 2023, The SPA Studios. All rights reserved.)
## adapted to create as a single 'GP as image' and fit in camera with driver
import bpy
from bpy_extras.io_utils import ImportHelper
from bpy.props import (StringProperty,
CollectionProperty,
BoolProperty,
EnumProperty)
import json
import bpy_extras
from mathutils import Vector
import os
from pathlib import Path
from .. import core
from .. constants import *
from .. export_psd_layers import export_psd_bg
from . core import import_planes, get_json_infos
class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper):
bl_idname = "bpm.import_bg_images"
bl_label = "Import Background images"
bl_description = "Import either a Json, a PSD, multiple files"
bl_options = {"REGISTER"} # , "INTERNAL"
# filename_ext = '.json'
filter_glob: StringProperty(
default=';'.join([f'*{i}' for i in bpy.path.extensions_image]) + ';*.json',
options={'HIDDEN'} )
## Active selection
filepath : StringProperty(
name="File Path",
description="File path used for import",
maxlen= 1024) # the active file
## Handle multi-selection
files: CollectionProperty(
name="File Path",
type=bpy.types.OperatorFileListElement,
) # The filelist collection
## Choice to place before or after ?
import_type : EnumProperty(
name="Import As", description="Type of import to ", default='GPENCIL', options={'ANIMATABLE'},
items=(
('GPENCIL', 'Gpencil Object', 'Import bg planes as gpencil objects', 0),
('EMPTY', 'Empty Reference', 'Import bg planes as empty objects', 1),
('MESH', 'Texture Plane', 'Import bg planes as mesh objects', 2),
))
mode : EnumProperty(
name="Mode", description="", default='REPLACE', options={'ANIMATABLE'},
items=(
('REPLACE', 'Replace Existing', 'Replace the image if already exists', 0),
('SKIP', 'Skip Existing', 'Skip the import if the image alreaady exists in planes', 1),
# ('PURGE', 'Purge', 'When object exists, fully delete it before linking, even associated collection and holder', 2),
))
def execute(self, context):
org_image_size = None
scn = context.scene
active_file = Path(self.filepath)
if len(self.files) == 1 and active_file.suffix.lower() in ('.json', '.psd'):
json_path = None
print('active_file.suffix.lower(): ', active_file.suffix.lower())
if active_file.suffix.lower() == '.psd':
print('Is a PSD')
## Export layers and create json setup file
# Export passes in a 'render' or 'render_hd' folder aside psd
json_path = export_psd_bg(str(active_file))
elif active_file.suffix.lower() == '.json':
print('Is a json')
# Use json data to batch import
json_path = active_file
if not json_path:
self.report({'ERROR'}, 'No json path to load, you can try loading from psd or selecting image file directly')
return {'CANCELLED'}
file_list, org_image_size = get_json_infos(json_path)
folder = Path(json_path).parent # render folder
else:
folder = active_file.parent
# Filter out json (we may want ot import the PSD as imagelisted in bpy.path.extensions_image)
file_list = [folder / f.name for f in self.files if Path(f.name).suffix in bpy.path.extensions_image]
if not file_list:
self.report({'ERROR'}, 'Image file list is empty')
return {'CANCELLED'}
## simple_list
# existing_backgrounds = [o for o in context.scene.objects if o.get('is_background')]
# existing_holders = [o for o in context.scene.objects if o.name.startswith(PREFIX) and o.type == 'MESH' and o.children]
## Has dict
# existing_backgrounds = {o : img_info for o in context.scene.objects if o.get('is_background') and (img_info := o.get('is_background'))}
# FIXME: Use existing background custom prop? : o.get('is_background')
## list of Tuples : [(plane_object, img_data, transparency_value), ...]
import_planes(file_list, import_type=self.import_type, image_size=org_image_size)
return {"FINISHED"}
classes = (
BPM_OT_import_bg_images,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)

View File

@ -1,11 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from . import (manage_objects, manage_planes, import_planes, convert_planes)
from . import (manage_objects, manage_planes, convert_planes)
modules = (
manage_objects,
manage_planes,
import_planes,
convert_planes
)

View File

@ -6,7 +6,7 @@ import re
# from bpy_extras.io_utils import ImportHelper
from pathlib import Path
from bpy.types import Operator
from .. import fn
from .. import core
from .. constants import BGCOL, MODULE_DIR
## Plane conversion between multiple types: GP plane / image plane / empty references
@ -29,7 +29,7 @@ def convert_background_image(ob, target = 'GPENCIL'):
return
# Get info from Source
img_infos = fn.get_image_infos_from_object(ob)
img_infos = core.get_image_infos_from_object(ob)
if not img_infos:
print(f'No could not retrieve image source from {ob}')
return
@ -51,8 +51,7 @@ def convert_background_image(ob, target = 'GPENCIL'):
suffix = ''
if target == 'GPENCIL':
## Create GP plane from Texture source
new = fn.import_image_as_gp_reference(
bpy.context,
new = core.import_image_as_gp_reference(
image_data,
pack_image=False,
)
@ -62,24 +61,24 @@ def convert_background_image(ob, target = 'GPENCIL'):
## 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 = fn.link_nodegroup(blend, 'texture_plane', link=False)
new = fn.create_image_plane(image_data, node_group)
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 = fn.create_empty_image(image_data)
new = core.create_empty_image(image_data)
suffix = '_texempty'
# Strip after '.' or get original name ?
print('source name: ', new.name)
new.name = fn.clean_image_name(image_data.name) + suffix
new.name = core.clean_image_name(image_data.name) + suffix
print('final name:', new.name)
new['is_background'] = True
## Without holder
## Transfer attributes
# fn.create_plane_driver(new, cam)
# core.create_plane_driver(new, cam)
# new.parent = cam
# new['distance'] = ob['distance']
@ -102,13 +101,13 @@ def convert_background_image(ob, target = 'GPENCIL'):
## Transfer current transparency
# Destination
fn.set_opacity(new, opacity)
core.set_opacity(new, opacity)
## Set in collection
if not len(ob.users_collection):
fn.set_collection(new, BGCOL)
core.set_collection(new, BGCOL)
else:
fn.set_collection(new, ob.users_collection[0].name)
core.set_collection(new, ob.users_collection[0].name)
## Remove old object
bpy.data.objects.remove(ob)
@ -136,7 +135,7 @@ class BPM_OT_convert_planes(Operator):
def execute(self, context):
print('BPM_OT_convert_planes')
holder_list = fn.scan_backgrounds(all_bg=True)
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'}

View File

@ -1,263 +0,0 @@
# SPDX-License-Identifier: GPL-3.0-or-later
## Standalone based on SPA code
## Code from create_gp_texture_ref.py (Copyright (C) 2023, The SPA Studios. All rights reserved.)
## adapted to create as a single 'GP as image' and fit in camera with driver
import bpy
from bpy_extras.io_utils import ImportHelper
from bpy.props import (StringProperty,
CollectionProperty,
BoolProperty,
EnumProperty)
import json
import bpy_extras
from mathutils import Vector
import os
from pathlib import Path
from .. import fn
from .. constants import *
from .. export_psd_layers import export_psd_bg
def get_json_infos(json_path) -> tuple((list, tuple)):
'''return a tuple with (image paths list, [x, y] original psd resolution'''
import json
setup_json_path = Path(json_path)
setup_json = json.loads(setup_json_path.read_text())
# psd = Path(setup_json['psd']) # path to psd
# image_size = setup_json['image_size'] # image size (reduced)
# png_dir = Path(setup_json['png_dir']) # path to png directory
layers = setup_json['layers'] # dic : name, lbbox, bbox, index, path
org_image_size = setup_json['org_image_size'] # original PSD dimensions
img_list = [Path(l['path']) for l in layers] # (png_dir /l['name']).with_suffix('.png')
return img_list, org_image_size
def setup_bg_camera(image_size, context=None, scn=None, cam_type=None):
'''Create background camera from scene active camera according to background image resolution
image_size ::
cam_type :: wether the BG camera should be set to perspective or orthographic
'''
context = context or bpy.context
scn=scn or context.scene
movie_resolution = scn.render.resolution_x, scn.render.resolution_y
anim_cam = scn.camera
anim_cam_scale = 6 # anim_cam.data.ortho_scale
anim_cam_focale = 50 # anim_cam.data.lens
cam_type = cam_type or anim_cam.data.type
## scale up plane scale and bg_cam ortho_scale according to film res
bg_factor = (anim_cam_scale * image_size[0]) / movie_resolution[0]
#print(f'({anim_cam_scale} * {image_size[0]}) / {movie_resolution[0]} = {bg_factor}')
## scale down the focal according to film res
bg_focale = (anim_cam_focale * movie_resolution[0]) / image_size[0]
#print(f'({anim_cam_focale} * {movie_resolution[0]}) / {image_size[0]} = {bg_focale}')
bg_cam = scn.objects.get('bg_cam')
if not bg_cam:
bg_cam = fn.create_cam(name='bg_cam', type=cam_type, size=bg_factor, focale=bg_focale)
bg_cam['resolution'] = image_size
bg_cam.matrix_world = anim_cam.matrix_world
bg_cam.hide_select = True
bg_cam.lock_location = bg_cam.lock_rotation = bg_cam.lock_scale = [True]*3
fn.set_collection(bg_cam, 'Camera')
fn.set_collection(anim_cam, 'Camera')
return bg_cam
class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper):
bl_idname = "bpm.import_bg_images"
bl_label = "Import Background images"
bl_description = "Import either a Json, a PSD, multiple files"
bl_options = {"REGISTER"} # , "INTERNAL"
# filename_ext = '.json'
filter_glob: StringProperty(
default=';'.join([f'*{i}' for i in bpy.path.extensions_image]) + ';*.json',
options={'HIDDEN'} )
## Active selection
filepath : StringProperty(
name="File Path",
description="File path used for import",
maxlen= 1024) # the active file
## Handle multi-selection
files: CollectionProperty(
name="File Path",
type=bpy.types.OperatorFileListElement,
) # The filelist collection
## Choice to place before or after ?
import_type : EnumProperty(
name="Import As", description="Type of import to ", default='GPENCIL', options={'ANIMATABLE'},
items=(
('GPENCIL', 'Gpencil Object', 'Import bg planes as gpencil objects', 0),
('EMPTY', 'Empty Reference', 'Import bg planes as empty objects', 1),
('MESH', 'Texture Plane', 'Import bg planes as mesh objects', 2),
))
mode : EnumProperty(
name="Mode", description="", default='REPLACE', options={'ANIMATABLE'},
items=(
('REPLACE', 'Replace Existing', 'Replace the image if already exists', 0),
('SKIP', 'Skip Existing', 'Skip the import if the image alreaady exists in planes', 1),
# ('PURGE', 'Purge', 'When object exists, fully delete it before linking, even associated collection and holder', 2),
))
def execute(self, context):
org_image_size = None
scn = context.scene
active_file = Path(self.filepath)
if len(self.files) == 1 and active_file.suffix.lower() in ('.json', '.psd'):
json_path = None
print('active_file.suffix.lower(): ', active_file.suffix.lower())
if active_file.suffix.lower() == '.psd':
print('Is a PSD')
## Export layers and create json setup file
# Export passes in a 'render' or 'render_hd' folder aside psd
json_path = export_psd_bg(str(active_file))
elif active_file.suffix.lower() == '.json':
print('Is a json')
# Use json data to batch import
json_path = active_file
if not json_path:
self.report({'ERROR'}, 'No json path to load, you can try loading from psd or selecting image file directly')
return {'CANCELLED'}
file_list, org_image_size = get_json_infos(json_path)
folder = Path(json_path).parent # render folder
else:
folder = active_file.parent
# Filter out json (we may want ot import the PSD as imagelisted in bpy.path.extensions_image)
file_list = [folder / f.name for f in self.files if Path(f.name).suffix in bpy.path.extensions_image]
if not file_list:
self.report({'ERROR'}, 'Image file list is empty')
return {'CANCELLED'}
## simple_list
# existing_backgrounds = [o for o in context.scene.objects if o.get('is_background')]
# existing_holders = [o for o in context.scene.objects if o.name.startswith(PREFIX) and o.type == 'MESH' and o.children]
## Has dict
# existing_backgrounds = {o : img_info for o in context.scene.objects if o.get('is_background') and (img_info := o.get('is_background'))}
# FIXME: Use existing background custom prop? : o.get('is_background')
## list of Tuples : [(plane_object, img_data, transparency_value), ...]
existing_backgrounds = [(o, *img_info) for o in context.scene.objects \
if o.get('is_background') and (img_info := fn.get_image_infos_from_object(o)) and o.get('is_background') and o.parent]
existing_backgrounds.sort(key=lambda x: x[0].parent.location.z, reverse=True) # sort by parent (holder) location Z
far_plane = INIT_POS
if existing_backgrounds:
far_plane = existing_backgrounds[-1][0].parent.location.z
## Ensure bg_cam setup (option to use active camera ?)
bg_cam = scn.objects.get('bg_cam')
if not bg_cam:
if not org_image_size:
## Get image size from first file
img = bpy.data.images.load(file_list[0], check_existing=True)
org_image_size = (img.size[0], img.size[1])
bg_cam = setup_bg_camera(
org_image_size, context=context, scn=scn, cam_type=scn.camera.data.type)
## Ensure Background collection
backgrounds = fn.get_col(BGCOL) # Create if needed
for fp in file_list:
print(f'Importing {fp.name}')
current_holder = None
file_stem = Path(fp).stem
# current_bg = next((o for o if o.parent and fn.get_image_infos_from_object(o)), None)
current_bg = next((o for o in existing_backgrounds if o[1].filepath == fp), None)
if current_bg:
current_holder = current_bg.parent
# TODO store opacity or delete existing objects only after loop
if current_bg and self.mode == 'SKIP':
print(f' - SKIP: existing {current_bg.name}')
continue
if current_bg and self.mode == 'REPLACE':
print(f' - DEL: existing {current_bg.name}')
bpy.data.objects.remove(current_bg)
# Import image
if self.import_type == 'GPENCIL':
bg_img = fn.import_image_as_gp_reference(
context=context,
image=fp,
pack_image=False,
)
elif self.import_type == 'MESH':
bg_img = fn.create_image_plane(fp)
elif self.import_type == 'EMPTY':
bg_img = fn.create_empty_image(fp)
bg_img.name = file_stem + '_texgp'
bg_img.hide_select = True
if current_holder:
bg_img.parent = current_holder
fn.set_collection(bg_img, current_holder.users_collection[0].name)
continue
# img, opacity = fn.get_image_infos_from_object(bg_img)
print('bg_img: ', bg_img)
img = fn.get_image(bg_img)
# bg_name = fn.clean_image_name(img.name)
file_stem = file_stem
# Get create collection from image clean name
bg_col = fn.get_col(file_stem, parent=backgrounds)
## Set in collection
bg_col.objects.link(bg_img)
print('img: ', img.name, bg_img.name, bg_img.users_collection)
## create the holder, parent to camera, set driver and set collection. Could also pass 'fp'
holder = fn.create_plane_holder(img, name=PREFIX + file_stem, parent=bg_cam, link_in_col=bg_col)
print('holder: ', holder.name)
fn.create_plane_driver(holder, bg_cam, distance=far_plane)
bg_img.parent = holder
far_plane += 2
fn.reload_bg_list(scene=scn)
self.report({'INFO'}, f'Settings loaded from: {os.path.basename(self.filepath)}')
return {"FINISHED"}
classes=(
BPM_OT_import_bg_images,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)

View File

@ -6,7 +6,7 @@ import mathutils
from bpy.types import Operator
from mathutils import Matrix, Vector
from .. import fn
from .. import core
def set_resolution_from_cam_prop(cam=None):
@ -292,8 +292,8 @@ class BPM_OT_create_and_place_in_camera(Operator):
self.create = False
## Set placeholder name (Comment to let an empty string)
self.name = fn.placeholder_name(self.name, context)
prefs = fn.get_addon_prefs()
self.name = core.placeholder_name(self.name, context)
prefs = core.get_addon_prefs()
self.use_light = prefs.use_light
self.edit_line_opacity = prefs.edit_line_opacity
@ -306,9 +306,9 @@ class BPM_OT_create_and_place_in_camera(Operator):
if settings.planes and settings.planes[settings.index].plane:
plane = settings.planes[settings.index].plane
self.distance = fn.coord_distance_from_cam_straight(plane.matrix_world.to_translation()) - 0.005
self.distance = core.coord_distance_from_cam_straight(plane.matrix_world.to_translation()) - 0.005
else:
self.distance = fn.coord_distance_from_cam_straight(context.scene.cursor.location)
self.distance = core.coord_distance_from_cam_straight(context.scene.cursor.location)
self.distance = max([1.0, self.distance]) # minimum one meter away from cam
if self.create:
@ -331,10 +331,10 @@ class BPM_OT_create_and_place_in_camera(Operator):
def execute(self, context):
if self.create:
ob_name = fn.placeholder_name(self.name, context)
ob_name = core.placeholder_name(self.name, context)
## Create Object
prefs = fn.get_addon_prefs()
prefs = core.get_addon_prefs()
gp_data = bpy.data.grease_pencils.new(ob_name)
ob = bpy.data.objects.new(ob_name, gp_data)
ob.use_grease_pencil_lights = prefs.use_light
@ -342,7 +342,7 @@ class BPM_OT_create_and_place_in_camera(Operator):
l = gp_data.layers.new('GP_Layer')
l.frames.new(context.scene.frame_current)
fn.set_collection(ob, 'GP') # Gpencils
core.set_collection(ob, 'GP') # Gpencils
# Add to bg_plane collection
new_item = context.scene.bg_props.planes.add()
@ -351,7 +351,7 @@ class BPM_OT_create_and_place_in_camera(Operator):
# Set active on last
context.scene.bg_props.index = len(context.scene.bg_props.planes) - 1
fn.gp_transfer_mode(ob)
core.gp_transfer_mode(ob)
loaded_palette = False
if hasattr(bpy.types, "GPTB_OT_load_default_palette"):

View File

@ -5,7 +5,7 @@ from bpy.types import Operator
from mathutils import Vector
from os.path import abspath
from .. import fn
from .. import core
from .. constants import BGCOL
## Open image folder
@ -39,7 +39,7 @@ class BPM_OT_open_bg_folder(Operator):
self.report({'ERROR'}, f'Could not found child for holder: {ob.name}')
return {"CANCELLED"}
img = fn.get_image(tex_obj)
img = core.get_image(tex_obj)
fp = Path(abspath(bpy.path.abspath(img.filepath)))
if not fp.exists():
self.report({'ERROR'}, f'Not found: {fp}')
@ -290,7 +290,7 @@ class BPM_OT_reload(Operator):
return True
def execute(self, context):
error = fn.reload_bg_list()
error = core.reload_bg_list()
if error:
if isinstance(error, list):
self.report({'WARNING'}, 'Wrong name for some object, see console:' + '\n'.join(error))

View File

@ -1,6 +1,6 @@
import bpy
from pathlib import Path
from .. import fn
from .. import core
from .. constants import PREFIX
from bpy.types import UIList, PropertyGroup, Menu
from bpy.props import (PointerProperty,
@ -51,7 +51,7 @@ class BPM_UL_bg_list(UIList):
return
layercol = context.view_layer.layer_collection.children['Background'].children.get(fn.clean_image_name(item.plane.name[len(PREFIX):]))
layercol = context.view_layer.layer_collection.children['Background'].children.get(core.clean_image_name(item.plane.name[len(PREFIX):]))
if not layercol:
layout.label(text=f'{item.plane.name} (problem with name)', icon='ERROR')
return
@ -63,7 +63,7 @@ class BPM_UL_bg_list(UIList):
layout.label(text=f'{item.plane.name} (No children)', icon='ERROR')
## Image preview
image = fn.get_image(item.plane.children[0])
image = core.get_image(item.plane.children[0])
# layout.label(icon_value=image.preview_ensure().icon_id)
# layout.template_icon(icon_value=image.preview_ensure().icon_id)
@ -169,7 +169,7 @@ class BPM_UL_bg_list(UIList):
## TODO: Find a better solution to get the collection
## Get Collection from plane name -> problem: prefix "BG_" and suffix
layercol = context.view_layer.layer_collection.children['Background'].children.get(fn.clean_image_name(item.plane.name[len(PREFIX):]))
layercol = context.view_layer.layer_collection.children['Background'].children.get(core.clean_image_name(item.plane.name[len(PREFIX):]))
if not layercol:
layout.label(text=f'{item.plane.name} (problem with name)', icon='ERROR')
return
@ -181,7 +181,7 @@ class BPM_UL_bg_list(UIList):
layout.label(text=f'{item.plane.name} (No children)', icon='ERROR')
## Image preview
image = fn.get_image(item.plane.children[0])
image = core.get_image(item.plane.children[0])
# layout.label(icon_value=image.preview_ensure().icon_id)
# layout.template_icon(icon_value=image.preview_ensure().icon_id)
@ -270,7 +270,7 @@ def update_opacity(self, context):
for ob in pool:
if not ob or not ob.children:
continue
fn.set_opacity(ob.children[0], opacity=context.scene.bg_props.opacity)
core.set_opacity(ob.children[0], opacity=context.scene.bg_props.opacity)
def update_on_index_change(self, context):
# print('index change:', context.scene.bg_props.index)
@ -287,13 +287,13 @@ def update_on_index_change(self, context):
plane = item.plane
if not plane.children:
return
opacity = fn.get_opacity(plane.children[0])
opacity = core.get_opacity(plane.children[0])
if not opacity:
return
props['opacity'] = opacity
elif item.type == 'obj':
fn.gp_transfer_mode(item.plane, context)
core.gp_transfer_mode(item.plane, context)
def update_select(self, context):