first verison of layer name builder

1.5.3

- feat: quick-prefix for layer using pref separator
  - list editable in addon pref
  - add interface button above layers
- code: added environnement variable for prefix and separator:
  - `PREFIXES` : list of prefix (comma separated uppercase letters between 1 and 6 character, ex: 'AN,SP,L')
  - `SEPARATOR` : Separator character to determine prefixes, default is '_' (should not be a special regex character)
- UI: add addon prefs namespace ui-box in project settings
gpv2
Pullusb 2021-06-24 16:12:20 +02:00
parent f599964296
commit 0740e835d8
6 changed files with 167 additions and 14 deletions

View File

@ -1,6 +1,17 @@
# Changelog
1.5.3
- feat: layer aquick-prefix for layer using pref separator
- list editable in addon pref
- add interface button above layers
- code: added environnement variable for prefix and separator:
- `PREFIXES` : list of prefix (comma separated uppercase letters between 1 and 6 character, ex: 'AN,SP,L')
- `SEPARATOR` : Separator character to determine prefixes, default is '_' (should not be a special regex character)
- UI: add addon prefs namespace ui-box in project settings
1.5.2
- add environnement variables to set addon preferences project settings at register through `os.getenv('KEY')`:

116
OP_layer_name_builder.py Normal file
View File

@ -0,0 +1,116 @@
import bpy
import re
from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty
from .utils import get_addon_prefs
# --- OPS ---
## multi-prefix solution (Caps letters)
class PROJ_OT_layer_name_build(Operator):
bl_idname = "gp.layer_name_build"
bl_label = "Layer Name Build"
bl_description = "Change prefix of layer name"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return True
prefix : StringProperty(default='', options={'SKIP_SAVE'})
prefix2 : StringProperty(default='', options={'SKIP_SAVE'})
desc : StringProperty(default='', options={'SKIP_SAVE'})
def execute(self, context):
prefs = get_addon_prefs()
sep = prefs.separator
ob = context.object
gpl = ob.data.layers
act = gpl.active
if not act:
self.report({'ERROR'}, 'no layer active')
return {"CANCELLED"}
name = act.info
# pattern = r'([A-Z]{2})?_?([A-Z]{2})?_?(.*)' # bad ! match whithout separator
# pattern = r'(?:(^[A-Z]{2})_)?(?:([A-Z]{2})_)?(.*)' # matching only two letter
# pattern = r'^([A-Z]{2}_)?([A-Z]{2}_)?(.*)' # matching letters with separator
pattern = r'^([A-Z]{1,6}_)?([A-Z]{1,6}_)?(.*)' # matching capital letters from one to six
pattern = pattern.replace('_', sep) # set separator
res = re.search(pattern, name)
p1, p2, p3 = res.group(1), res.group(2), res.group(3)
## empty instead of None
p1 = '' if p1 is None else p1
p2 = '' if p2 is None else p2
p3 = '' if p3 is None else p3
if self.prefix:
if self.prefix == 'prefixkillcode':
p1 = ''
else:
p1 = self.prefix.upper() + sep
if self.prefix2:
p2 = self.prefix2.upper() + sep
if self.desc:
p3 = self.desc
new = f'{p1}{p2}{p3}'
act.info = new
return {"FINISHED"}
## --- UI ---
def layer_name_builder(self, context):
prefs = get_addon_prefs()
if not prefs.prefixes:
return
layout = self.layout
# {'EDIT_GPENCIL', 'PAINT_GPENCIL','SCULPT_GPENCIL','WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}
# layout.separator()
col = layout.column()
all_prefixes = prefs.prefixes.split(',')
line_limit = 8
## first prefix
for i, prefix in enumerate(all_prefixes):
if i % line_limit == 0:
row = col.row(align=True)
row.operator("gp.layer_name_build", text=prefix.upper() ).prefix = prefix
row.operator("gp.layer_name_build", text='', icon='X').prefix = 'prefixkillcode'
## secondary prefix
# row = layout.row(align=True)
# for task in prefs.prefixes: # 'PO', 'AN'
# row.operator("me.set_layer_name", text=task).prefix2 = task
row = col.row(align=True)
row.prop(context.scene.gptoolprops, 'layer_name', text='')
row.operator("gp.layer_name_build", text='', icon='EVENT_RETURN').desc = context.scene.gptoolprops.layer_name
classes=(
PROJ_OT_layer_name_build,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.DATA_PT_gpencil_layers.prepend(layer_name_builder)
def unregister():
bpy.types.DATA_PT_gpencil_layers.remove(layer_name_builder)
for cls in reversed(classes):
bpy.utils.unregister_class(cls)

View File

@ -31,13 +31,17 @@ Note about palette : For now the importer is not working with linked palette as
### Environnement Variables
Since 1.5.2, Following _environnement variable_ can set the project properties in toolbox preferences at register launch.
> Mainly for devellopers to set project environnement
Since 1.5.2, following _environnement variable_ can set the project properties in toolbox preferences at register launch.
`RENDER_WIDTH` : resolution x
`RENDER_HEIGHT` : resolution y
`FPS` : project frame rate
`PALETTES` : path to the blends (or json) containing materials palettes
`BRUSHES` : path to the blend containing brushes to load
`PREFIXES` : list of prefix (comma separated uppercase letters between 1 and 6 character, ex: 'AN,SP,L')
`SEPARATOR` : Separator character to determine prefixes, default is '_' (should not be a special regex character)
### Passive action

View File

@ -14,6 +14,8 @@ Il est recommandé de désactiver l'addon natif "Grease pencil tools" car ces o
### Variables d'environnement
> Cette partie s'adresse surtout aux dévellopeurs qui préparent les environement de projets.
Depuis la version 1.5.2, les variables d'environnement suivantes peuvent surcharger les préférences projet dans blender (au moment du register)
`RENDER_WIDTH` : résolution x
@ -21,6 +23,8 @@ Depuis la version 1.5.2, les variables d'environnement suivantes peuvent surchar
`FPS` : Vitesse du projet
`PALETTES` : Chemin vers le dossier des blends (ou json) contenant des palettes de matériaux
`BRUSHES` : Chemin vers le dossier des blends contenant les brushes a charger
`PREFIXES` : Liste de prefixes du projet pour les noms de calques
`SEPARATOR` : Caractère de séparation pour determiner les prefixes, par défaut '_' (ne doit pas être un caractère spécial de regex !)
### Exposition dans l'UI de fonction native

View File

@ -15,7 +15,7 @@ bl_info = {
"name": "GP toolbox",
"description": "Set of tools for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux",
"version": (1, 5, 2),
"version": (1, 5, 3),
"blender": (2, 91, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "",
@ -48,6 +48,7 @@ from . import OP_copy_paste
from . import OP_realign
from . import OP_depth_move
from . import OP_key_duplicate_send
from . import OP_layer_name_builder
from . import OP_eraser_brush
from . import TOOL_eraser_brush
from . import handler_draw_cam
@ -167,7 +168,7 @@ class GPTB_prefs(bpy.types.AddonPreferences):
## addon prefs
## Project preferences
#--# PROJECT PREFERENCES #--#
# subtype (string) Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD', 'NONE'].
## fps
@ -201,11 +202,6 @@ class GPTB_prefs(bpy.types.AddonPreferences):
description="Path relative to blend to place render",
default="//render", maxlen=0, subtype='DIR_PATH')
separator : StringProperty(
name="Namespace separator",
description="Character delimiter to use for detecting namespace (prefix), default is '_', space if nothing specified",
default="_", maxlen=0, subtype='NONE')
use_env_palettes : BoolProperty(
name="Use Project Palettes",
description="Load the palette path in environnement at startup (key 'PALETTES')",
@ -228,6 +224,16 @@ class GPTB_prefs(bpy.types.AddonPreferences):
description="Path to brushes containing the blends holding the brushes",
default="//", maxlen=0, subtype='DIR_PATH')#, update = set_palette_path
separator : StringProperty(
name="Separator",
description="Character delimiter to use for detecting namespace (prefix), default is '_', space if nothing specified",
default="_", maxlen=0, subtype='NONE')
prefixes : StringProperty(
name="Layers Prefixes",
description="List of prefixes (two capital letters) available for layers(ex: AN,CO,CL)",
default="", maxlen=0)
## Playblast prefs
playblast_auto_play : BoolProperty(
name="Playblast auto play",
@ -363,6 +369,13 @@ class GPTB_prefs(bpy.types.AddonPreferences):
## render output
subbox.prop(self, 'output_path')
## render output
subbox = box.box()
subbox.label(text='Namespace:')
subbox.prop(self, 'separator')
subbox.prop(self, 'prefixes')
box.prop(self, 'use_relative_remap_on_save')
### TODO add render settings
@ -416,10 +429,6 @@ class GPTB_prefs(bpy.types.AddonPreferences):
box.prop(self, "render_obj_exclusion", icon='FILTER')#
## random color character separator
box = layout.box()
box.label(text='Random color options:')
box.prop(self, 'separator')
box = layout.box()
box.label(text='Tools options:')
@ -479,8 +488,6 @@ class GPTB_prefs(bpy.types.AddonPreferences):
col.prop(self.fixprops, 'autokey_add_n_replace')
# row.label(text='lock the active camera if not a draw cam (and if not "layout" in blendfile name)')
if self.pref_tabs == 'UPDATE':
addon_updater_ops.update_settings_ui(self, context)
@ -508,6 +515,11 @@ def set_env_properties():
if prefs.use_env_brushes:
prefs.brush_path = brushes if brushes else prefs.brush_path
prefix_list = os.getenv('PREFIXES')
prefs.prefixes = prefix_list if prefix_list else prefs.prefixes
separator = os.getenv('SEPARATOR')
prefs.separator = separator if separator else prefs.separator
### --- REGISTER ---
@ -546,6 +558,7 @@ def register():
OP_realign.register()
OP_depth_move.register()
OP_key_duplicate_send.register()
OP_layer_name_builder.register()
OP_eraser_brush.register()
TOOL_eraser_brush.register()
handler_draw_cam.register()
@ -574,6 +587,7 @@ def unregister():
handler_draw_cam.unregister()
OP_eraser_brush.unregister()
TOOL_eraser_brush.unregister()
OP_layer_name_builder.unregister()
OP_key_duplicate_send.unregister()
OP_depth_move.unregister()
OP_realign.unregister()

View File

@ -127,6 +127,10 @@ class GP_PG_ToolsSettings(bpy.types.PropertyGroup):
('JITTER', 'Jitter', '', 'KEYTYPE_JITTER_VEC', 5),
))
layer_name : StringProperty(
name="Layer Name",
description="The layer name, should describe the content of the layer",
default="")# update=None, get=None, set=None
"""
reconnect_parent = bpy.props.PointerProperty(type =bpy.types.Object,poll=poll_armature)
render_settings = bpy.props.BoolProperty(default = False)