From 87c27c12d3505cf5a9c658dad7a392f14c983f1b Mon Sep 17 00:00:00 2001 From: pullusb Date: Mon, 26 May 2025 18:36:06 +0200 Subject: [PATCH] migrate code to GPV3 (still problem with UV fill not set on point anymore) --- __init__.py | 4 +-- core.py | 56 +++++++++++++++++++++++-------------- export_psd_layers.py | 2 +- import_planes/core.py | 4 +-- import_planes/operators.py | 4 +-- operators/convert_planes.py | 10 +++---- operators/manage_objects.py | 6 ++-- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/__init__.py b/__init__.py index bdf2c5b..bb67e8b 100644 --- a/__init__.py +++ b/__init__.py @@ -4,8 +4,8 @@ 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, 5, 4), - "blender": (3, 5, 0), + "version": (0, 6, 0), + "blender": (4, 3, 0), "location": "View3D", "warning": "", "doc_url": "https://gitlab.com/autour-de-minuit/blender/background_plane_manager", diff --git a/core.py b/core.py index c6b477e..302974c 100644 --- a/core.py +++ b/core.py @@ -74,7 +74,7 @@ def get_image_infos_from_object(ob): image_data = tex_node.image transparency = node.inputs['Transparency'].default_value - elif ob.type == 'GPENCIL': + elif ob.type == 'GREASEPENCIL': image_data = ob.data.materials[0].grease_pencil.fill_image transparency = ob.data.layers[0].opacity @@ -111,7 +111,7 @@ def set_opacity(ob, opacity): if n.type == 'GROUP' and n.node_tree is texture_plane_ng) node.inputs['Transparency'].default_value = opacity - elif ob.type == 'GPENCIL': + elif ob.type == 'GREASEPENCIL': ob.data.layers[0].opacity = opacity def create_plane_holder(img, name=None, parent=None, link_in_col=None): @@ -345,7 +345,7 @@ def placeholder_name(name='', context=None) -> str: # Create a default name (fing last 3 number, before blender increment if exists, default increment) numbers = [int(match.group(1)) for o in context.scene.objects\ if (match := re.search(r'^drawing.*_(\d+)(?:\.\d{3})?$', o.name, flags=re.I))\ - # and o.type == 'GPENCIL' + # and o.type == 'GREASEPENCIL' ] if numbers: numbers.sort() @@ -361,7 +361,7 @@ def placeholder_name(name='', context=None) -> str: def reset_gp_uv(ob): uvs = [(0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5), (0.5, -0.5)] try: - for p, uv in zip(ob.data.layers[0].frames[0].strokes[0].points, uvs): + for p, uv in zip(ob.data.layers[0].frames[0].drawing.strokes[0].points, uvs): p.uv_fill = uv except: print('Could not set Gp points UV') @@ -396,10 +396,10 @@ def get_ref_object_space_coord(o): ## Generate GP object def create_gpencil_reference( - gpd: bpy.types.GreasePencil, - gpf: bpy.types.GPencilFrame, + gpd: bpy.types.GreasePencilv3, + gpf: bpy.types.GreasePencilFrame, image: bpy.types.Image, -) -> bpy.types.GPencilStroke: +): # -> bpy.types.GPencilStroke (not sure which type to use) """ Add a rectangular stroke textured with `image` to the given grease pencil fame. :param gpd: The grease pencil data. @@ -427,13 +427,12 @@ def create_gpencil_reference( mat.grease_pencil.texture_clamp = True # Create the stroke - gps_new = gpf.strokes.new() - gps_new.points.add(4, pressure=0, strength=0) - + gpf.drawing.add_strokes([4]) + gps_new = gpf.drawing.strokes[-1] ## This will make sure that the uv's always remain the same # gps_new.use_automatic_uvs = False # <<- /!\ exists only in SPA core changes - gps_new.use_cyclic = True + gps_new.cyclic = True gps_new.material_index = idx x,y = image.size[:] @@ -459,9 +458,24 @@ def create_gpencil_reference( uvs = [(0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5), (0.5, -0.5)] + + # gpf.drawing.attriutes # add uv_fill for i, (co, uv) in enumerate(zip(coords, uvs)): - gps_new.points[i].co = co - gps_new.points[i].uv_fill = uv + gps_new.points[i].position = co + ## TODO: Set uv on + # gps_new.points[i].uv_fill = uv # uv_fill + gps_new.points[i].radius = 0 + gps_new.points[i].opacity = 0 + + ## Attribute are only created if gradient (or something similar) is used, creating manually + gpf.drawing.attributes.new('uv_translation', 'FLOAT2', 'CURVE') + gpf.drawing.attributes.new('uv_scale', 'FLOAT2', 'CURVE') + gpf.drawing.attributes.new('uv_rotation', 'FLOAT', 'CURVE') + + ## TODO Set the right UV value on fist () + gpf.drawing.attributes['uv_translation'].data[0].vector = (0.0, 0.0) + gpf.drawing.attributes['uv_scale'].data[0].vector = (1.0, 1.0) + gpf.drawing.attributes['uv_rotation'].data[0].value = 0.0 return gps_new @@ -484,7 +498,7 @@ def import_image_as_gp_reference( image = bpy.data.images.load(str(image), check_existing=True) ## Create grease pencil object - gpd = bpy.data.grease_pencils.new(image.name) + gpd = bpy.data.grease_pencils_v3.new(image.name) ob = bpy.data.objects.new(image.name, gpd) gpl = gpd.layers.new(image.name) gpf = gpl.frames.new(0) # TDOO: test negative @@ -492,7 +506,7 @@ def import_image_as_gp_reference( if pack_image: image.pack() - gps: bpy.types.GPencilStroke = create_gpencil_reference( + gps = create_gpencil_reference( # : bpy.types.GPencilStroke typehint might be for annotation gpd, gpf, image, @@ -510,13 +524,13 @@ def import_image_as_gp_reference( def gp_transfer_mode(ob, context=None): context= context or bpy.context - if ob.type != 'GPENCIL' or context.object is ob: + if ob.type != 'GREASEPENCIL' or context.object is ob: return prev_mode = context.mode possible_gp_mods = ('OBJECT', - 'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'PAINT_GPENCIL', - 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL') + 'EDIT_GREASE_PENCIL', 'SCULPT_GREASE_PENCIL', 'PAINT_GREASE_PENCIL', + 'WEIGHT_GREASE_PENCIL', 'VERTEX_GREASE_PENCIL') if prev_mode not in possible_gp_mods: prev_mode = None @@ -543,7 +557,7 @@ def gp_transfer_mode(ob, context=None): if context.mode != prev_mode is not None: bpy.ops.object.mode_set(mode=prev_mode) - for o in [o for o in context.scene.objects if o.type == 'GPENCIL']: + for o in [o for o in context.scene.objects if o.type == 'GREASEPENCIL']: o.select_set(o == ob) # select only active (when not in object mode) ## generate tex plane @@ -781,11 +795,11 @@ def reload_bg_list(scene=None): item.plane = ob item.type = "bg" scn.bg_props.index = len(uilist) - 1 # id (len of list in the ad loop) - if ob.children and ob.children[0].type == 'GPENCIL': + if ob.children and ob.children[0].type == 'GREASEPENCIL': reset_gp_uv(ob.children[0]) # Force reset UV ## Add Grease pencil objects - gp_list = [o for o in bpy.context.scene.objects if o.type == 'GPENCIL' \ + gp_list = [o for o in bpy.context.scene.objects if o.type == 'GREASEPENCIL' \ and not o.get('is_background') and o not in oblist] for ob in gp_list: item = uilist.add() diff --git a/export_psd_layers.py b/export_psd_layers.py index 7484af6..8ba8ec4 100644 --- a/export_psd_layers.py +++ b/export_psd_layers.py @@ -240,7 +240,7 @@ class BPM_OT_export_psd_layers(bpy.types.Operator, ImportHelper): # path_to_pal : bpy.props.StringProperty(name="paht to palette", description="path to the palette", default="") @classmethod def poll(cls, context): - return context.object and context.object.type == 'GPENCIL' + return context.object and context.object.type == 'GREASEPENCIL' filename_ext = '.psd' diff --git a/import_planes/core.py b/import_planes/core.py index 44726d6..62f1c68 100644 --- a/import_planes/core.py +++ b/import_planes/core.py @@ -68,7 +68,7 @@ def setup_bg_camera(image_size, scene=None, cam_type=None): set_collection(anim_cam, 'Camera') return bg_cam -def import_planes(images, import_type='GPENCIL', mode='REPLACE', image_size=None): +def import_planes(images, import_type='GREASEPENCIL', mode='REPLACE', image_size=None): scn = bpy.context.scene existing_backgrounds = [(o, *img_info) for o in scn.objects \ @@ -113,7 +113,7 @@ def import_planes(images, import_type='GPENCIL', mode='REPLACE', image_size=None bpy.data.objects.remove(current_bg) # Import image - if import_type == 'GPENCIL': + if import_type == 'GREASEPENCIL': bg_img = import_image_as_gp_reference( image=str(image_path), pack_image=False, diff --git a/import_planes/operators.py b/import_planes/operators.py index 7f0d600..e8408a5 100644 --- a/import_planes/operators.py +++ b/import_planes/operators.py @@ -49,9 +49,9 @@ class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper): ## Choice to place before or after ? import_type : EnumProperty( - name="Import As", description="Type of import to ", default='GPENCIL', options={'ANIMATABLE'}, + name="Import As", description="Type of import to ", default='GREASEPENCIL', options={'ANIMATABLE'}, items=( - ('GPENCIL', 'Gpencil Object', 'Import bg planes as gpencil objects', 0), + ('GREASEPENCIL', '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), )) diff --git a/operators/convert_planes.py b/operators/convert_planes.py index b535244..a138019 100644 --- a/operators/convert_planes.py +++ b/operators/convert_planes.py @@ -11,8 +11,8 @@ 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']''' +def convert_background_image(ob, target = 'GREASEPENCIL'): + '''Target in ['GREASEPENCIL', 'EMPTY', 'MESH']''' if target == ob.type: print('WARNING', f'{ob.name} Already of type {target}') @@ -49,7 +49,7 @@ def convert_background_image(ob, target = 'GPENCIL'): ## TODO: ensure image filepath is ok ? suffix = '' - if target == 'GPENCIL': + if target == 'GREASEPENCIL': ## Create GP plane from Texture source new = core.import_image_as_gp_reference( image_data, @@ -122,9 +122,9 @@ class BPM_OT_convert_planes(Operator): bl_options = {"REGISTER"} # , "UNDO" target_type : bpy.props.EnumProperty( - name="Convert To", description="", default='GPENCIL', options={'ANIMATABLE'}, + name="Convert To", description="", default='GREASEPENCIL', options={'ANIMATABLE'}, items=( - ('GPENCIL', 'Gpencil Object', 'Convert bg planes to gpencil objects', 0), + ('GREASEPENCIL', '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), )) diff --git a/operators/manage_objects.py b/operators/manage_objects.py index 3acf120..829884c 100644 --- a/operators/manage_objects.py +++ b/operators/manage_objects.py @@ -240,9 +240,9 @@ class BPM_OT_align_to_plane(Operator): for l in o.data.layers: for f in l.frames: - for s in f.strokes: + for s in f.drawing.strokes: for p in s.points: - p.co = matrot @ p.co + p.position = matrot @ p.position return {"FINISHED"} @@ -341,7 +341,7 @@ class BPM_OT_create_and_place_in_camera(Operator): ## Create Object prefs = core.get_addon_prefs() - gp_data = bpy.data.grease_pencils.new(ob_name) + gp_data = bpy.data.grease_pencils_v3.new(ob_name) ob = bpy.data.objects.new(ob_name, gp_data) ob.use_grease_pencil_lights = prefs.use_light gp_data.edit_line_color[3] = prefs.edit_line_opacity