migrate code to GPV3 (still problem with UV fill not set on point anymore)

This commit is contained in:
pullusb 2025-05-26 18:36:06 +02:00
parent 0bd062d212
commit 87c27c12d3
7 changed files with 50 additions and 36 deletions

View File

@ -4,8 +4,8 @@ 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, 5, 4), "version": (0, 6, 0),
"blender": (3, 5, 0), "blender": (4, 3, 0),
"location": "View3D", "location": "View3D",
"warning": "", "warning": "",
"doc_url": "https://gitlab.com/autour-de-minuit/blender/background_plane_manager", "doc_url": "https://gitlab.com/autour-de-minuit/blender/background_plane_manager",

56
core.py
View File

@ -74,7 +74,7 @@ def get_image_infos_from_object(ob):
image_data = tex_node.image image_data = tex_node.image
transparency = node.inputs['Transparency'].default_value transparency = node.inputs['Transparency'].default_value
elif ob.type == 'GPENCIL': elif ob.type == 'GREASEPENCIL':
image_data = ob.data.materials[0].grease_pencil.fill_image image_data = ob.data.materials[0].grease_pencil.fill_image
transparency = ob.data.layers[0].opacity 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) if n.type == 'GROUP' and n.node_tree is texture_plane_ng)
node.inputs['Transparency'].default_value = opacity node.inputs['Transparency'].default_value = opacity
elif ob.type == 'GPENCIL': elif ob.type == 'GREASEPENCIL':
ob.data.layers[0].opacity = opacity ob.data.layers[0].opacity = opacity
def create_plane_holder(img, name=None, parent=None, link_in_col=None): 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) # 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\ 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))\ if (match := re.search(r'^drawing.*_(\d+)(?:\.\d{3})?$', o.name, flags=re.I))\
# and o.type == 'GPENCIL' # and o.type == 'GREASEPENCIL'
] ]
if numbers: if numbers:
numbers.sort() numbers.sort()
@ -361,7 +361,7 @@ def placeholder_name(name='', context=None) -> str:
def reset_gp_uv(ob): def reset_gp_uv(ob):
uvs = [(0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5), (0.5, -0.5)] uvs = [(0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5), (0.5, -0.5)]
try: 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 p.uv_fill = uv
except: except:
print('Could not set Gp points UV') print('Could not set Gp points UV')
@ -396,10 +396,10 @@ def get_ref_object_space_coord(o):
## Generate GP object ## Generate GP object
def create_gpencil_reference( def create_gpencil_reference(
gpd: bpy.types.GreasePencil, gpd: bpy.types.GreasePencilv3,
gpf: bpy.types.GPencilFrame, gpf: bpy.types.GreasePencilFrame,
image: bpy.types.Image, 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. Add a rectangular stroke textured with `image` to the given grease pencil fame.
:param gpd: The grease pencil data. :param gpd: The grease pencil data.
@ -427,13 +427,12 @@ def create_gpencil_reference(
mat.grease_pencil.texture_clamp = True mat.grease_pencil.texture_clamp = True
# Create the stroke # Create the stroke
gps_new = gpf.strokes.new() gpf.drawing.add_strokes([4])
gps_new.points.add(4, pressure=0, strength=0) gps_new = gpf.drawing.strokes[-1]
## This will make sure that the uv's always remain the same ## 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_automatic_uvs = False # <<- /!\ exists only in SPA core changes
gps_new.use_cyclic = True gps_new.cyclic = True
gps_new.material_index = idx gps_new.material_index = idx
x,y = image.size[:] 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)] 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)): for i, (co, uv) in enumerate(zip(coords, uvs)):
gps_new.points[i].co = co gps_new.points[i].position = co
gps_new.points[i].uv_fill = uv ## 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 return gps_new
@ -484,7 +498,7 @@ def import_image_as_gp_reference(
image = bpy.data.images.load(str(image), check_existing=True) image = bpy.data.images.load(str(image), check_existing=True)
## Create grease pencil object ## 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) ob = bpy.data.objects.new(image.name, gpd)
gpl = gpd.layers.new(image.name) gpl = gpd.layers.new(image.name)
gpf = gpl.frames.new(0) # TDOO: test negative gpf = gpl.frames.new(0) # TDOO: test negative
@ -492,7 +506,7 @@ def import_image_as_gp_reference(
if pack_image: if pack_image:
image.pack() image.pack()
gps: bpy.types.GPencilStroke = create_gpencil_reference( gps = create_gpencil_reference( # : bpy.types.GPencilStroke typehint might be for annotation
gpd, gpd,
gpf, gpf,
image, image,
@ -510,13 +524,13 @@ def import_image_as_gp_reference(
def gp_transfer_mode(ob, context=None): def gp_transfer_mode(ob, context=None):
context= context or bpy.context context= context or bpy.context
if ob.type != 'GPENCIL' or context.object is ob: if ob.type != 'GREASEPENCIL' or context.object is ob:
return return
prev_mode = context.mode prev_mode = context.mode
possible_gp_mods = ('OBJECT', possible_gp_mods = ('OBJECT',
'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'PAINT_GPENCIL', 'EDIT_GREASE_PENCIL', 'SCULPT_GREASE_PENCIL', 'PAINT_GREASE_PENCIL',
'WEIGHT_GPENCIL', 'VERTEX_GPENCIL') 'WEIGHT_GREASE_PENCIL', 'VERTEX_GREASE_PENCIL')
if prev_mode not in possible_gp_mods: if prev_mode not in possible_gp_mods:
prev_mode = None prev_mode = None
@ -543,7 +557,7 @@ def gp_transfer_mode(ob, context=None):
if context.mode != prev_mode is not None: if context.mode != prev_mode is not None:
bpy.ops.object.mode_set(mode=prev_mode) 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) o.select_set(o == ob) # select only active (when not in object mode)
## generate tex plane ## generate tex plane
@ -781,11 +795,11 @@ def reload_bg_list(scene=None):
item.plane = ob item.plane = ob
item.type = "bg" item.type = "bg"
scn.bg_props.index = len(uilist) - 1 # id (len of list in the ad loop) 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 reset_gp_uv(ob.children[0]) # Force reset UV
## Add Grease pencil objects ## 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] and not o.get('is_background') and o not in oblist]
for ob in gp_list: for ob in gp_list:
item = uilist.add() item = uilist.add()

View File

@ -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="") # path_to_pal : bpy.props.StringProperty(name="paht to palette", description="path to the palette", default="")
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.object and context.object.type == 'GPENCIL' return context.object and context.object.type == 'GREASEPENCIL'
filename_ext = '.psd' filename_ext = '.psd'

View File

@ -68,7 +68,7 @@ def setup_bg_camera(image_size, scene=None, cam_type=None):
set_collection(anim_cam, 'Camera') set_collection(anim_cam, 'Camera')
return bg_cam 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 scn = bpy.context.scene
existing_backgrounds = [(o, *img_info) for o in scn.objects \ 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) bpy.data.objects.remove(current_bg)
# Import image # Import image
if import_type == 'GPENCIL': if import_type == 'GREASEPENCIL':
bg_img = import_image_as_gp_reference( bg_img = import_image_as_gp_reference(
image=str(image_path), image=str(image_path),
pack_image=False, pack_image=False,

View File

@ -49,9 +49,9 @@ class BPM_OT_import_bg_images(bpy.types.Operator, ImportHelper):
## Choice to place before or after ? ## Choice to place before or after ?
import_type : EnumProperty( 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=( 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), ('EMPTY', 'Empty Reference', 'Import bg planes as empty objects', 1),
('MESH', 'Texture Plane', 'Import bg planes as mesh objects', 2), ('MESH', 'Texture Plane', 'Import bg planes as mesh objects', 2),
)) ))

View File

@ -11,8 +11,8 @@ from .. constants import BGCOL, MODULE_DIR
## Plane conversion between multiple types: GP plane / image plane / empty references ## Plane conversion between multiple types: GP plane / image plane / empty references
def convert_background_image(ob, target = 'GPENCIL'): def convert_background_image(ob, target = 'GREASEPENCIL'):
'''Target in ['GPENCIL', 'EMPTY', 'MESH']''' '''Target in ['GREASEPENCIL', 'EMPTY', 'MESH']'''
if target == ob.type: if target == ob.type:
print('WARNING', f'{ob.name} Already of type {target}') 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 ? ## TODO: ensure image filepath is ok ?
suffix = '' suffix = ''
if target == 'GPENCIL': if target == 'GREASEPENCIL':
## Create GP plane from Texture source ## Create GP plane from Texture source
new = core.import_image_as_gp_reference( new = core.import_image_as_gp_reference(
image_data, image_data,
@ -122,9 +122,9 @@ class BPM_OT_convert_planes(Operator):
bl_options = {"REGISTER"} # , "UNDO" bl_options = {"REGISTER"} # , "UNDO"
target_type : bpy.props.EnumProperty( target_type : bpy.props.EnumProperty(
name="Convert To", description="", default='GPENCIL', options={'ANIMATABLE'}, name="Convert To", description="", default='GREASEPENCIL', options={'ANIMATABLE'},
items=( 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), ('EMPTY', 'Empty Reference', 'Convert bg planes to empty objects', 1),
('MESH', 'Texture Plane', 'Convert bg planes to mesh objects', 2), ('MESH', 'Texture Plane', 'Convert bg planes to mesh objects', 2),
)) ))

View File

@ -240,9 +240,9 @@ class BPM_OT_align_to_plane(Operator):
for l in o.data.layers: for l in o.data.layers:
for f in l.frames: for f in l.frames:
for s in f.strokes: for s in f.drawing.strokes:
for p in s.points: for p in s.points:
p.co = matrot @ p.co p.position = matrot @ p.position
return {"FINISHED"} return {"FINISHED"}
@ -341,7 +341,7 @@ class BPM_OT_create_and_place_in_camera(Operator):
## Create Object ## Create Object
prefs = core.get_addon_prefs() 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 = bpy.data.objects.new(ob_name, gp_data)
ob.use_grease_pencil_lights = prefs.use_light ob.use_grease_pencil_lights = prefs.use_light
gp_data.edit_line_color[3] = prefs.edit_line_opacity gp_data.edit_line_color[3] = prefs.edit_line_opacity