From 0740e835d8be6c4af002952f91e8cfaf0a094b15 Mon Sep 17 00:00:00 2001 From: Pullusb Date: Thu, 24 Jun 2021 16:12:20 +0200 Subject: [PATCH] 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 --- CHANGELOG.md | 11 ++++ OP_layer_name_builder.py | 116 +++++++++++++++++++++++++++++++++++++++ README.md | 6 +- README_FR.md | 4 ++ __init__.py | 40 +++++++++----- properties.py | 4 ++ 6 files changed, 167 insertions(+), 14 deletions(-) create mode 100644 OP_layer_name_builder.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea832d..5a79c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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')`: diff --git a/OP_layer_name_builder.py b/OP_layer_name_builder.py new file mode 100644 index 0000000..282f5fb --- /dev/null +++ b/OP_layer_name_builder.py @@ -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) \ No newline at end of file diff --git a/README.md b/README.md index 983204f..e65e70c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/README_FR.md b/README_FR.md index ef500ef..0e0b93b 100644 --- a/README_FR.md +++ b/README_FR.md @@ -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 diff --git a/__init__.py b/__init__.py index cd28475..8bea5e0 100755 --- a/__init__.py +++ b/__init__.py @@ -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() diff --git a/properties.py b/properties.py index aa6a882..4897d86 100755 --- a/properties.py +++ b/properties.py @@ -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)