2022-03-24 14:41:32 +01:00
# SPDX-License-Identifier: GPL-2.0-or-later
2021-01-10 16:47:17 +01:00
bl_info = {
2021-01-19 19:49:16 +01:00
" name " : " GP toolbox " ,
2021-12-04 13:57:32 +01:00
" description " : " Tool set for Grease Pencil in animation production " ,
2021-06-16 17:35:17 +02:00
" author " : " Samuel Bernou, Christophe Seux " ,
2022-11-23 15:25:28 +01:00
" version " : ( 2 , 1 , 2 ) ,
2022-10-08 15:46:44 +02:00
" blender " : ( 3 , 0 , 0 ) ,
2021-06-05 01:20:35 +02:00
" location " : " Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties " ,
2021-01-10 16:47:17 +01:00
" warning " : " " ,
" doc_url " : " https://gitlab.com/autour-de-minuit/blender/gp_toolbox " ,
2021-01-14 23:36:05 +01:00
" tracker_url " : " https://gitlab.com/autour-de-minuit/blender/gp_toolbox/-/issues " ,
2021-01-10 16:47:17 +01:00
" category " : " 3D View " ,
}
2022-01-23 16:27:30 +01:00
from pathlib import Path
from shutil import which
2022-02-22 11:29:31 +01:00
from sys import modules
2021-10-28 14:33:37 +02:00
from . utils import get_addon_prefs , draw_kmi
2021-01-10 16:47:17 +01:00
## GMIC
from . GP_guided_colorize import GP_colorize
## direct tools
from . import OP_breakdowner
from . import OP_temp_cutter
from . import OP_playblast_bg
from . import OP_playblast
from . import OP_helpers
2021-01-19 01:11:18 +01:00
from . import OP_keyframe_jump
2021-01-10 16:47:17 +01:00
from . import OP_cursor_snap_canvas
from . import OP_palettes
2021-11-25 17:00:09 +01:00
from . import OP_palettes_linker
2021-06-14 17:41:41 +02:00
from . import OP_brushes
2021-01-10 16:47:17 +01:00
from . import OP_file_checker
from . import OP_copy_paste
2021-05-04 23:17:19 +02:00
from . import OP_realign
2022-01-18 22:53:08 +01:00
from . import OP_flat_reproject
2021-05-09 01:26:37 +02:00
from . import OP_depth_move
2021-05-24 17:06:10 +02:00
from . import OP_key_duplicate_send
2021-06-25 18:17:51 +02:00
from . import OP_layer_manager
2021-10-28 14:33:37 +02:00
from . import OP_layer_picker
2021-12-22 14:11:31 +01:00
from . import OP_layer_nav
2021-07-27 18:48:38 +02:00
from . import OP_material_picker
2022-01-23 16:27:30 +01:00
from . import OP_git_update
2022-10-13 00:09:12 +02:00
from . import OP_layer_namespace
from . import OP_pseudo_tint
2022-11-04 18:45:37 +01:00
from . import OP_follow_curve
2022-03-24 18:25:56 +01:00
# from . import OP_eraser_brush
# from . import TOOL_eraser_brush
2021-05-30 23:51:18 +02:00
from . import handler_draw_cam
2021-01-10 16:47:17 +01:00
from . import keymaps
from . import UI_tools
2022-10-03 00:08:10 +02:00
from . properties import (
GP_PG_ToolsSettings ,
GP_PG_FixSettings ,
GP_PG_namespaces ,
)
2021-01-10 16:47:17 +01:00
from bpy . props import ( FloatProperty ,
BoolProperty ,
EnumProperty ,
StringProperty ,
2022-10-03 00:08:10 +02:00
IntProperty ,
PointerProperty
)
2021-01-10 16:47:17 +01:00
import bpy
2021-06-23 16:30:30 +02:00
import os
2021-01-10 16:47:17 +01:00
from bpy . app . handlers import persistent
from pathlib import Path
# from .eyedrop import EyeDropper
# from .properties import load_icons,remove_icons
### prefs
# def set_palette_path(self, context):
# print('value set')
# self.palette_path = Path(bpy.path.abspath(self["palette_path"])).as_posix()
2021-03-07 00:39:32 +01:00
@persistent
def remap_relative ( dummy ) :
2021-05-05 18:33:34 +02:00
# try:
2021-03-07 00:39:32 +01:00
all_path = [ lib for lib in bpy . utils . blend_paths ( local = True ) ]
bpy . ops . file . make_paths_relative ( )
for i , lib in enumerate ( bpy . utils . blend_paths ( local = True ) ) :
if all_path [ i ] != lib :
print ( ' Remapped: ' , all_path [ i ] , ' \n >> ' , lib )
2021-05-05 18:33:34 +02:00
# except Exception as e:
# print(e)
2021-03-07 00:39:32 +01:00
def remap_on_save_update ( self , context ) :
pref = get_addon_prefs ( )
if pref . use_relative_remap_on_save :
if not ' remap_relative ' in [ hand . __name__ for hand in bpy . app . handlers . save_pre ] :
bpy . app . handlers . save_pre . append ( remap_relative )
else :
if ' remap_relative ' in [ hand . __name__ for hand in bpy . app . handlers . save_pre ] :
bpy . app . handlers . save_pre . remove ( remap_relative )
2021-06-16 17:35:17 +02:00
2022-03-24 18:25:56 +01:00
## precise eraser
# def update_use_precise_eraser(self, context):
# km, kmi = TOOL_eraser_brush.addon_keymaps[0]
# kmi.active = self.use_precise_eraser
2021-06-16 17:35:17 +02:00
2021-01-10 16:47:17 +01:00
class GPTB_prefs ( bpy . types . AddonPreferences ) :
bl_idname = __name__
2022-03-24 18:25:56 +01:00
## precise eraser
# use_precise_eraser : BoolProperty(
# name='Precise Eraser',
# default=False,
# update=update_use_precise_eraser)
2021-01-10 16:47:17 +01:00
## tabs
2021-03-07 00:39:32 +01:00
pref_tabs : EnumProperty (
2021-01-10 16:47:17 +01:00
items = ( ( ' PREF ' , " Preferences " , " Change some preferences of the modal " ) ,
2021-10-29 16:49:38 +02:00
( ' KEYS ' , " Shortcuts " , " Customize addon shortcuts " ) ,
( ' MAN_OPS ' , " Operators " , " Operator to add Manually " ) ,
2021-06-17 16:21:27 +02:00
( ' CHECKS ' , " Check List " , " Customise what should happend when hitting ' check fix ' button " ) ,
2021-08-23 14:50:00 +02:00
# ('UPDATE', "Update", "Check and apply updates"),
# ('TUTO', "Tutorial", "How to use the tool"),
2021-01-10 16:47:17 +01:00
# ('KEYMAP', "Keymap", "customise the default keymap"),
) ,
default = ' PREF ' )
## addon prefs
2021-06-24 16:12:20 +02:00
#--# PROJECT PREFERENCES #--#
2021-01-10 16:47:17 +01:00
# subtype (string) – Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD', 'NONE'].
2022-01-23 16:27:30 +01:00
# update variables
is_git_repo : BoolProperty ( default = False )
has_git : BoolProperty ( default = False )
2021-01-10 16:47:17 +01:00
## fps
2021-03-07 00:39:32 +01:00
use_relative_remap_on_save : BoolProperty (
name = " Relative Remap On Save " ,
description = " Always remap all external path to relative when saving \n Need blender restart if changed " ,
2021-05-05 18:33:34 +02:00
default = False ,
2021-03-07 00:39:32 +01:00
update = remap_on_save_update
)
2021-01-10 16:47:17 +01:00
fps : IntProperty (
name = ' Frame Rate ' ,
description = " Fps of the project, Used to conform the file when you use Check file operator " ,
2021-06-17 16:21:27 +02:00
default = 24 ,
2021-01-10 16:47:17 +01:00
min = 1 ,
max = 10000
)
## output settings for automated renders
output_parent_level = IntProperty (
name = ' Parent level ' ,
description = " Go up in folder to define a render path relative to the file in upper directotys " ,
default = 0 ,
min = 0 ,
max = 20
)
output_path : StringProperty (
name = " Output path " ,
description = " Path relative to blend to place render " ,
default = " //render " , maxlen = 0 , subtype = ' DIR_PATH ' )
2022-03-24 18:25:56 +01:00
playblast_path : StringProperty (
name = " Playblast Path " ,
description = " Path to folder for playblasts output " ,
default = " //playblast " , maxlen = 0 , subtype = ' DIR_PATH ' )
2021-06-23 16:30:30 +02:00
use_env_palettes : BoolProperty (
name = " Use Project Palettes " ,
description = " Load the palette path in environnement at startup (key ' PALETTES ' ) " ,
default = True ,
)
2021-01-10 16:47:17 +01:00
palette_path : StringProperty (
name = " Palettes directory " ,
description = " Path to palette containing palette.json files to save and load " ,
2021-08-23 14:50:00 +02:00
default = " " , maxlen = 0 , subtype = ' DIR_PATH ' ) #, update = set_palette_path
warn_base_palette : BoolProperty (
name = " Warn if base palette isn ' t loaded " ,
description = " Display a button to load palette base.json if current grease pencil has a no ' line ' and ' invisible ' materials " ,
default = True ,
)
2021-01-10 16:47:17 +01:00
2022-01-19 11:36:45 +01:00
mat_link_exclude : StringProperty (
name = " Materials Link Exclude " ,
description = " List of material name to exclude when using palette linker (separate multiple value with comma, ex: line, rough) " ,
default = " line, " , maxlen = 0 )
2021-06-23 16:30:30 +02:00
use_env_brushes : BoolProperty (
name = " Use Project Brushes " ,
description = " Load the brushes path in environnement at startup (key ' BRUSHES ' ) " ,
default = True ,
)
2021-06-14 17:41:41 +02:00
brush_path : StringProperty (
name = " Brushes directory " ,
description = " Path to brushes containing the blends holding the brushes " ,
default = " // " , maxlen = 0 , subtype = ' DIR_PATH ' ) #, update = set_palette_path
2021-09-07 15:41:54 +02:00
## namespace
2021-06-24 16:12:20 +02:00
separator : StringProperty (
name = " Separator " ,
description = " Character delimiter to use for detecting namespace (prefix), default is ' _ ' , space if nothing specified " ,
default = " _ " , maxlen = 0 , subtype = ' NONE ' )
2022-10-09 00:28:14 +02:00
## Old one string comma separated prefix/suffix list
2022-10-08 01:15:34 +02:00
# prefixes : StringProperty(
# name="Layers Prefixes",
# description="List of prefixes (two capital letters) available for layers(ex: AN,CO,CL)",
# default="", maxlen=0)
2022-10-03 00:08:10 +02:00
2022-10-09 00:28:14 +02:00
# suffixes : StringProperty(
# name="Layers Suffixes",
# description="List of suffixes (two capital letters) available for layers(ex: OL,UL)",
# default="", maxlen=0)
2022-10-08 01:15:34 +02:00
prefixes : PointerProperty ( type = GP_PG_namespaces )
2022-10-09 00:28:14 +02:00
suffixes : PointerProperty ( type = GP_PG_namespaces )
2021-06-24 16:12:20 +02:00
2021-07-20 18:53:39 +02:00
2021-09-07 15:41:54 +02:00
# use_env_namespace : BoolProperty(
# name="Use Project namespace",
# description="Ovewrite prefix/suffix with Project values defined in environnement at startup\n(key 'PREFIXES and SUFFIXES')",
# default=True,
# )
2021-07-20 18:53:39 +02:00
show_prefix_buttons : BoolProperty (
name = " Show Prefix Buttons " ,
description = " Show prefix and suffix buttons above layer stack " ,
2022-10-08 01:15:34 +02:00
default = True ,
2021-07-20 18:53:39 +02:00
)
2021-01-10 16:47:17 +01:00
## Playblast prefs
playblast_auto_play : BoolProperty (
name = " Playblast auto play " ,
description = " Open rendered playblast when finished " ,
default = True ,
)
playblast_auto_open_folder : BoolProperty (
name = " Playblast auto open location " ,
description = " Open folder of rendered playblast when finished " ,
default = False ,
)
## render settings
render_obj_exclusion : StringProperty (
name = " GP obj exclude filter " ,
description = " List comma separated words to exclude from render list " ,
default = " old,rough,trash,test " ) #, subtype='FILE_PATH')
render_res_x : IntProperty (
name = ' Resolution X ' ,
description = " Resolution on X " ,
default = 2048 ,
min = 1 ,
max = 10000
)
render_res_y : IntProperty (
name = ' Resolution Y ' ,
description = " Resolution on Y " ,
default = 1080 ,
min = 1 ,
max = 10000
)
2021-01-19 01:11:18 +01:00
## KF jumper
kfj_use_shortcut : BoolProperty (
name = " Use Keyframe Jump Shortcut " ,
2021-05-02 23:14:38 +02:00
description = " Auto bind shotcut for keyframe jump (else you can bind manually using ' screen.gp_keyframe_jump ' id_name) " ,
2021-01-19 01:11:18 +01:00
default = True )
kfj_prev_keycode : StringProperty (
name = " Jump Prev Shortcut " ,
description = " Shortcut to trigger previous keyframe jump " ,
default = " F5 " )
kfj_prev_shift : BoolProperty (
name = " Shift " ,
description = " add shift " ,
default = False )
kfj_prev_alt : BoolProperty (
name = " Alt " ,
description = " add alt " ,
default = False )
kfj_prev_ctrl : BoolProperty (
name = " combine with ctrl " ,
description = " add ctrl " ,
default = False )
kfj_next_keycode : StringProperty (
name = " Jump Next Shortcut " ,
description = " Shortcut to trigger keyframe jump " ,
default = " F6 " )
kfj_next_shift : BoolProperty (
name = " Shift " ,
description = " add shift " ,
default = False )
kfj_next_alt : BoolProperty (
name = " Alt " ,
description = " add alt " ,
default = False )
kfj_next_ctrl : BoolProperty (
name = " combine with ctrl " ,
description = " add ctrl " ,
default = False )
2021-06-17 16:21:27 +02:00
fixprops : bpy . props . PointerProperty ( type = GP_PG_FixSettings )
2021-12-22 14:11:31 +01:00
## GP Layer navigator
nav_use_fade : BoolProperty (
name = ' Fade Inactive Layers ' ,
description = ' Fade Inactive layers to determine active layer in a glimpse ' ,
default = True )
nav_fade_val : FloatProperty (
name = ' Fade Value ' ,
description = ' Fade value for other layers when navigating (0=invisible) ' ,
default = 0.35 , min = 0.0 , max = 0.95 , step = 1 , precision = 2 )
nav_limit : FloatProperty (
name = ' Fade Duration ' ,
description = ' Time of other layer faded when using layer navigation ' ,
default = 1.4 , min = 0.1 , max = 5 , step = 2 , precision = 1 , subtype = ' TIME ' , unit = ' TIME ' )
nav_use_fade_in : BoolProperty (
name = ' Progressive Fade Back ' ,
description = ' Use a fade on other layer when navigating ' ,
default = True )
nav_fade_in_time : FloatProperty (
name = ' Fade-In Time ' ,
description = ' Duration of the fade ' ,
default = 0.5 , min = 0.1 , max = 5 , step = 2 , precision = 2 , subtype = ' TIME ' , unit = ' TIME ' )
nav_interval : FloatProperty (
name = ' Refresh Rate ' ,
description = ' Refresh rate for fade updating (upper value means stepped fade) ' ,
default = 0.04 , min = 0.01 , max = 0.5 , step = 3 , precision = 2 , subtype = ' TIME ' , unit = ' TIME ' )
2021-01-10 16:47:17 +01:00
## Temp cutter
# temp_cutter_use_shortcut: BoolProperty(
# name = "Use temp cutter Shortcut",
# description = "Auto assign shortcut for temp_cutter",
# default = True)
2022-10-09 00:28:14 +02:00
def draw_namespaces_list ( self , layout , pg_name , rows = 4 ) :
''' Get layout, property group to draw and default row number '''
pg = getattr ( self , pg_name )
row = layout . row ( align = True )
row . template_list ( " GPTB_UL_namespace_list " , " " , pg , " namespaces " , pg , " idx " , rows = rows )
subcol = row . column ( align = True ) # Lateral right
subcol . operator ( " gptb.add_namespace_entry " , icon = " ADD " , text = " " ) . propname = pg_name
subcol . operator ( " gptb.remove_namespace_entry " , icon = " REMOVE " , text = " " ) . propname = pg_name
subcol . separator ( )
op_move = subcol . operator ( " gptb.move_item " , icon = " TRIA_UP " , text = " " )
op_move . propname = pg_name
op_move . direction = ' UP '
op_move = subcol . operator ( " gptb.move_item " , icon = " TRIA_DOWN " , text = " " )
op_move . propname = pg_name
op_move . direction = ' DOWN '
## Reset entry (Not needed anymore)
# subcol.separator()
# subcol.operator('prefs.reset_gp_toolbox_env', text='', icon='LOOP_BACK').mode = 'PREFIXES'
2021-01-10 16:47:17 +01:00
def draw ( self , context ) :
layout = self . layout ## random color
# layout.use_property_split = True
row = layout . row ( align = True )
row . prop ( self , " pref_tabs " , expand = True )
if self . pref_tabs == ' PREF ' :
box = layout . box ( )
box . label ( text = ' Project settings ' )
## Render
# box.label(text='Render option:')
box . prop ( self , ' fps ' )
row = box . row ( align = True )
2021-03-07 00:39:32 +01:00
row . label ( text = ' Render Resolution ' )
row . prop ( self , ' render_res_x ' , text = ' Width ' )
row . prop ( self , ' render_res_y ' , text = ' Height ' )
2021-06-23 16:30:30 +02:00
2021-06-24 16:40:22 +02:00
box . prop ( self , ' use_relative_remap_on_save ' )
box . prop ( self , " render_obj_exclusion " , icon = ' FILTER ' ) #
2021-06-23 16:30:30 +02:00
subbox = box . box ( )
2021-06-23 16:46:30 +02:00
subbox . label ( text = ' Project folders: ' )
## Palette
2021-06-23 16:30:30 +02:00
subbox . prop ( self , ' use_env_palettes ' , text = ' Use Palettes Environnement Path ' )
subbox . prop ( self , ' palette_path ' )
2021-08-23 14:50:00 +02:00
subbox . prop ( self , ' warn_base_palette ' )
2021-06-23 16:30:30 +02:00
2022-01-19 11:36:45 +01:00
subbox . prop ( self , ' mat_link_exclude ' )
2021-06-23 16:30:30 +02:00
## Brushes
subbox . prop ( self , ' use_env_brushes ' , text = ' Use Brushes Environnement Path ' )
subbox . prop ( self , ' brush_path ' )
2021-01-10 16:47:17 +01:00
## render output
2021-06-23 16:30:30 +02:00
subbox . prop ( self , ' output_path ' )
2021-06-24 16:12:20 +02:00
2021-09-07 15:41:54 +02:00
## namespace
2021-06-24 16:12:20 +02:00
subbox = box . box ( )
subbox . label ( text = ' Namespace: ' )
subbox . prop ( self , ' separator ' )
2021-07-20 18:53:39 +02:00
subbox . prop ( self , ' show_prefix_buttons ' , text = ' Use Prefixes Toggles ' )
2022-10-03 00:08:10 +02:00
2021-07-20 18:53:39 +02:00
if self . show_prefix_buttons :
2021-09-07 15:41:54 +02:00
# subbox.prop(self, 'use_env_namespace')
2022-10-08 01:15:34 +02:00
"""
2021-09-07 15:41:54 +02:00
row = subbox . row ( )
row . prop ( self , ' prefixes ' )
row . operator ( ' prefs.reset_gp_toolbox_env ' , text = ' ' , icon = ' LOOP_BACK ' ) . mode = ' PREFIXES '
2022-10-08 01:15:34 +02:00
row = subbox . row ( align = True )
row . prop ( self , ' suffixes ' )
row . operator ( ' prefs.reset_gp_toolbox_env ' , text = ' ' , icon = ' LOOP_BACK ' ) . mode = ' SUFFIXES '
2022-10-09 00:28:14 +02:00
"""
## Collection UI list version
self . draw_namespaces_list ( subbox , ' prefixes ' , rows = 4 )
subbox . separator ( )
self . draw_namespaces_list ( subbox , ' suffixes ' , rows = 4 )
2021-06-24 16:12:20 +02:00
2021-01-10 16:47:17 +01:00
### TODO add render settings
# layout.separator()## Playblast
box = layout . box ( )
box . label ( text = ' Playblast options: ' )
box . prop ( self , ' playblast_auto_play ' )
box . prop ( self , ' playblast_auto_open_folder ' )
2022-03-24 18:25:56 +01:00
box . prop ( self , ' playblast_path ' )
2021-01-10 16:47:17 +01:00
2021-01-19 01:11:18 +01:00
# box.separator()## Keyframe jumper
2021-10-29 16:49:38 +02:00
## Keyframe jump now displayed in Shortcut Tab
# box = layout.box()
# box.label(text='Keyframe Jump options:')
# box.prop(self, "kfj_use_shortcut", text='Bind shortcuts')
# if self.kfj_use_shortcut:
# prompt = '[TYPE SHORTCUT TO USE (can be with modifiers)]'
# if self.kfj_prev_keycode:
# mods = '+'.join([m for m, b in [('Ctrl', self.kfj_prev_ctrl), ('Shift', self.kfj_prev_shift), ('Alt', self.kfj_prev_alt)] if b])
# text = f'{mods}+{self.kfj_prev_keycode}' if mods else self.kfj_prev_keycode
# text = f'Jump Keyframe Prev: {text} (Click to change)'
# else:
# text = prompt
# ops = box.operator('prefs.shortcut_rebinder', text=text, icon='FILE_REFRESH')
# ops.s_keycode = 'kfj_prev_keycode'
# ops.s_ctrl = 'kfj_prev_ctrl'
# ops.s_shift = 'kfj_prev_shift'
# ops.s_alt = 'kfj_prev_alt'
# if self.kfj_next_keycode:
# mods = '+'.join([m for m, b in [('Ctrl', self.kfj_next_ctrl), ('Shift', self.kfj_next_shift), ('Alt', self.kfj_next_alt)] if b])
# text = f'{mods}+{self.kfj_next_keycode}' if mods else self.kfj_next_keycode
# text = f'Jump Keyframe Next: {text} (Click to change)'
# else:
# text = prompt
# ops = box.operator('prefs.shortcut_rebinder', text=text, icon='FILE_REFRESH')
# ops.s_keycode = 'kfj_next_keycode'
# ops.s_ctrl = 'kfj_next_ctrl'
# ops.s_shift = 'kfj_next_shift'
# ops.s_alt = 'kfj_next_alt'
2021-01-19 01:11:18 +01:00
2021-10-29 16:49:38 +02:00
# else:
# box.label(text="No Jump hotkey auto set. Following operators needs to be set manually", icon="ERROR")
# box.label(text="screen.gp_keyframe_jump - preferably in 'screen' category to jump from any editor")
2021-01-19 01:11:18 +01:00
2021-06-16 17:35:17 +02:00
box = layout . box ( )
box . label ( text = ' Tools options: ' )
2021-12-22 14:11:31 +01:00
subbox = box . box ( )
subbox . label ( text = ' Layer Navigation ' )
col = subbox . column ( )
col . prop ( self , ' nav_use_fade ' )
if self . nav_use_fade :
row = col . row ( )
row . prop ( self , ' nav_fade_val ' )
row . prop ( self , ' nav_limit ' )
row = subbox . row ( align = False )
row . prop ( self , ' nav_use_fade_in ' )
if self . nav_use_fade_in :
row . prop ( self , ' nav_fade_in_time ' , text = ' Fade Back Time ' )
# row.prop(self, 'nav_interval') # Do not expose refresh rate for now, not usefull to user...
2022-03-24 18:25:56 +01:00
# box.prop(self, 'use_precise_eraser') # precise eraser
2022-01-23 16:27:30 +01:00
if self . is_git_repo :
box = layout . box ( )
box . label ( text = ' Addon Update ' )
if self . is_git_repo and self . has_git :
box . operator ( ' gptb.git_pull ' , text = ' Check / Get Last Update ' , icon = ' PLUGIN ' )
else :
box . label ( text = ' Toolbox can be updated using git ' )
row = box . row ( )
row . operator ( ' wm.url_open ' , text = ' Download and install git here ' , icon = ' URL ' ) . url = ' https://git-scm.com/download/ '
row . label ( text = ' then restart blender ' )
2021-01-10 16:47:17 +01:00
2021-10-29 16:49:38 +02:00
if self . pref_tabs == ' KEYS ' :
# layout.label(text='Shortcuts :')
box = layout . box ( )
box . label ( text = ' Shortcuts added by GP toolbox with context scope: ' )
## not available directly :
## keymaps.addon_keymaps <<- one two three on sculpt, not exposed
## OP_temp_cutter # not active by defaut
## TOOL_eraser_brush.addon_keymaps # has a checkbox in
prev_key_category = ' '
for kms in [
OP_keyframe_jump . addon_keymaps ,
OP_copy_paste . addon_keymaps ,
2021-12-22 14:11:31 +01:00
OP_breakdowner . addon_keymaps ,
2021-10-29 16:49:38 +02:00
OP_key_duplicate_send . addon_keymaps ,
OP_layer_picker . addon_keymaps ,
OP_material_picker . addon_keymaps ,
2021-12-22 14:11:31 +01:00
OP_layer_nav . addon_keymaps ,
# OP_layer_manager.addon_keymaps, # Do not display, wm.call_panel call panel ops mixed with natives shortcut (F2)
2021-10-29 16:49:38 +02:00
] :
ct = 0
for akm , akmi in kms :
km = bpy . context . window_manager . keyconfigs . user . keymaps . get ( akm . name )
if not km :
continue
key_category = km . name
# kmi = km.keymap_items.get(akmi.idname) # get only first idname when multiple entry
kmi = None
## numbering hack, need a better way to find multi idname user keymaps
id_ct = 0
for km_item in km . keymap_items :
if km_item . idname == akmi . idname :
if ct > id_ct :
id_ct + = 1
continue
kmi = km_item
ct + = 1
break
if not kmi :
continue
## show keymap category (ideally grouped by category)
if not prev_key_category :
if key_category :
box . label ( text = key_category )
elif key_category and key_category != prev_key_category : # check if has changed singe
box . label ( text = key_category )
draw_kmi ( km , kmi , box )
prev_key_category = key_category
box . separator ( )
2021-01-10 16:47:17 +01:00
if self . pref_tabs == ' MAN_OPS ' :
# layout.separator()## notes
# layout.label(text='Notes:')
2021-03-31 01:38:17 +02:00
layout . label ( text = ' Following operators ID have to be set manually in keymap if needed : ' )
2021-01-10 16:47:17 +01:00
## keyframe jump
box = layout . box ( )
box . label ( text = ' GP keyframe jump (consider only GP keyframe, multiple options available at setup) ' )
row = box . row ( )
row . label ( text = ' screen.gp_keyframe_jump ' )
row . operator ( ' wm.copytext ' , icon = ' COPYDOWN ' ) . text = ' screen.gp_keyframe_jump '
# layout.separator()
## Snap cursor to GP
box = layout . box ( )
box . label ( text = ' Snap cursor to GP canvas (if not autoset) ' )
row = box . row ( )
row . label ( text = ' Look for default 3d snap operators by searching " view3d.cursor3d " ' )
row . operator ( ' wm.copytext ' , text = ' Copy " view3d.cursor3d " ' , icon = ' COPYDOWN ' ) . text = ' view3d.cursor3d '
row = box . row ( )
row . label ( text = ' Replace wanted by " view3d.cusor_snap " ' )
row . operator ( ' wm.copytext ' , text = ' Copy " view3d.cusor_snap " ' , icon = ' COPYDOWN ' ) . text = ' view3d.cusor_snap '
box . label ( text = ' Or just create a new shortcut using cursor_snap ' )
2021-03-31 01:38:17 +02:00
## Clear keyframe
box = layout . box ( )
box . label ( text = ' Clear active frame (delete all strokes without deleting the frame) ' )
row = box . row ( )
row . label ( text = ' gp.clear_active_frame ' )
row . operator ( ' wm.copytext ' , icon = ' COPYDOWN ' ) . text = ' gp.clear_active_frame '
2021-01-10 16:47:17 +01:00
## user prefs
box = layout . box ( )
box . label ( text = ' Note: You can access user pref file and startup file in config folder ' )
box . operator ( " wm.path_open " , text = ' Open config location ' ) . filepath = bpy . utils . user_resource ( ' CONFIG ' )
2021-06-17 16:21:27 +02:00
if self . pref_tabs == ' CHECKS ' :
layout . label ( text = ' Following checks will be made when clicking " Check File " button: ' )
col = layout . column ( )
2022-10-22 16:23:01 +02:00
col . use_property_split = True
2021-07-16 18:14:31 +02:00
col . prop ( self . fixprops , ' check_only ' )
2022-10-22 16:23:01 +02:00
col . label ( text = ' If dry run is checked, no modification is done ' , icon = ' INFO ' )
col . label ( text = ' Use Ctrl + Click on " Check File " button to invert the behavior ' , icon = ' BLANK1 ' )
2021-07-16 18:14:31 +02:00
col . separator ( )
2021-06-17 16:21:27 +02:00
col . prop ( self . fixprops , ' lock_main_cam ' )
col . prop ( self . fixprops , ' set_scene_res ' , text = f ' Reset Scene Resolution (to { self . render_res_x } x { self . render_res_y } ) ' )
col . prop ( self . fixprops , ' set_res_percentage ' )
col . prop ( self . fixprops , ' set_fps ' , text = f ' Reset FPS (to { self . fps } ) ' )
col . prop ( self . fixprops , ' set_slider_n_sync ' )
col . prop ( self . fixprops , ' check_front_axis ' )
col . prop ( self . fixprops , ' check_placement ' )
2022-01-18 22:53:08 +01:00
col . prop ( self . fixprops , ' set_gp_use_lights_off ' )
2021-06-17 16:21:27 +02:00
col . prop ( self . fixprops , ' set_pivot_median_point ' )
col . prop ( self . fixprops , ' disable_guide ' )
col . prop ( self . fixprops , ' list_disabled_anim ' )
2021-10-20 20:54:59 +02:00
col . prop ( self . fixprops , ' list_obj_vis_conflict ' )
col . prop ( self . fixprops , ' list_gp_mod_vis_conflict ' )
2022-02-02 17:08:41 +01:00
col . prop ( self . fixprops , ' list_broken_mod_targets ' )
2021-06-17 16:21:27 +02:00
col . prop ( self . fixprops , ' autokey_add_n_replace ' )
2021-06-28 12:41:56 +02:00
#-# col.prop(self.fixprops, 'set_cursor_type')
2022-10-22 16:23:01 +02:00
# col = layout.column()
# col.use_property_split = True
2021-06-24 16:40:22 +02:00
col . prop ( self . fixprops , " select_active_tool " , icon = ' RESTRICT_SELECT_OFF ' )
2021-06-28 12:41:56 +02:00
col . prop ( self . fixprops , " file_path_type " )
2021-07-16 18:14:31 +02:00
col . prop ( self . fixprops , " lock_object_mode " )
2021-06-17 16:21:27 +02:00
# row.label(text='lock the active camera if not a draw cam (and if not "layout" in blendfile name)')
2021-08-23 14:50:00 +02:00
# if self.pref_tabs == 'UPDATE':
# addon_updater_ops.update_settings_ui(self, context)
2021-01-10 16:47:17 +01:00
2021-06-23 16:30:30 +02:00
### --- ENV_PROP ---
2022-10-09 00:28:14 +02:00
def set_namespace_env ( name_env , prop_group ) :
tag_list = os . getenv ( name_env )
2022-10-25 17:24:05 +02:00
current_pfix = [ ]
2022-10-09 00:28:14 +02:00
if tag_list :
tag_list = tag_list . strip ( ' , ' ) . split ( ' , ' )
current_pfix = [ n . tag for n in prop_group . namespaces if n . tag ]
2022-11-04 18:45:37 +01:00
# for n in prop_group.namespaces:
# print(n.tag, n.name)
2022-10-09 00:28:14 +02:00
for p in tag_list :
2022-10-25 17:24:05 +02:00
tag = p . split ( ' : ' ) [ 0 ] . strip ( )
2022-10-09 00:28:14 +02:00
name = ' ' if not ' : ' in p else p . split ( ' : ' ) [ 1 ] . strip ( )
2022-10-25 17:24:05 +02:00
item = None
if tag not in current_pfix :
2022-10-09 00:28:14 +02:00
item = prop_group . namespaces . add ( )
2022-10-25 17:24:05 +02:00
item . tag = tag
2022-10-09 00:28:14 +02:00
item . name = name
item . is_project = True
2022-10-25 17:24:05 +02:00
print ( ' Loaded project tag: ' , tag , name )
elif name :
# get the tag and apply name
item = [ n for n in prop_group . namespaces if n . tag == tag ] [ 0 ]
if not item . name . strip ( ) :
item . name = name
print ( ' Loaded name: ' , name )
if item :
item . is_project = True
2022-10-09 00:28:14 +02:00
else :
tag_list = [ ]
# "release" suffix that are not in project anymore
for n in prop_group . namespaces :
2022-10-25 17:24:05 +02:00
if n . tag not in current_pfix :
2022-10-09 00:28:14 +02:00
n . is_project = False
2021-06-23 16:30:30 +02:00
def set_env_properties ( ) :
2022-10-09 00:28:14 +02:00
2021-06-23 16:30:30 +02:00
prefs = get_addon_prefs ( )
fps = os . getenv ( ' FPS ' )
2021-06-23 16:46:30 +02:00
prefs . fps = int ( fps ) if fps else prefs . fps
2021-06-23 16:30:30 +02:00
render_width = os . getenv ( ' RENDER_WIDTH ' )
2021-09-20 12:21:04 +02:00
prefs . render_res_x = int ( render_width ) if render_width else prefs . render_res_x
render_height = os . getenv ( ' RENDER_HEIGHT ' )
prefs . render_res_y = int ( render_height ) if render_height else prefs . render_res_y
2021-06-23 16:30:30 +02:00
palettes = os . getenv ( ' PALETTES ' )
if prefs . use_env_palettes :
prefs . palette_path = palettes if palettes else prefs . palette_path
brushes = os . getenv ( ' BRUSHES ' )
if prefs . use_env_brushes :
prefs . brush_path = brushes if brushes else prefs . brush_path
2021-09-07 15:41:54 +02:00
# if prefs.use_env_namespace:
2022-10-09 00:28:14 +02:00
## Old method with direct string assignment (now a property group)
# prefix_list = os.getenv('PREFIXES')
2022-10-08 01:15:34 +02:00
# prefs.prefixes = prefix_list if prefix_list else prefs.prefixes
2022-10-09 00:28:14 +02:00
# suffix_list = os.getenv('SUFFIXES')
# prefs.suffixes = suffix_list if suffix_list else prefs.suffixes
2022-10-08 01:15:34 +02:00
2022-10-09 00:28:14 +02:00
set_namespace_env ( ' PREFIXES ' , prefs . prefixes )
set_namespace_env ( ' SUFFIXES ' , prefs . suffixes )
2021-06-24 16:12:20 +02:00
separator = os . getenv ( ' SEPARATOR ' )
prefs . separator = separator if separator else prefs . separator
2021-06-23 16:30:30 +02:00
2021-09-07 15:41:54 +02:00
class GPTB_set_env_settings ( bpy . types . Operator ) :
""" manually reset prefs from project environnement setttings """
bl_idname = " prefs.reset_gp_toolbox_env "
bl_label = " Reset prefs from project environnement settings (if any) "
mode : bpy . props . StringProperty ( default = ' ALL ' , options = { ' SKIP_SAVE ' } ) # 'HIDDEN',
def execute ( self , context ) :
prefs = get_addon_prefs ( )
if self . mode == ' ALL ' :
set_env_properties ( )
elif self . mode == ' PREFIXES ' :
prefix_list = os . getenv ( ' PREFIXES ' )
if not prefix_list :
self . report ( { ' ERROR ' } , ' No prefix preset to load from project environnement ' )
return { ' CANCELLED ' }
2022-10-09 00:28:14 +02:00
set_namespace_env ( ' PREFIXES ' , prefs . prefixes )
2021-09-07 15:41:54 +02:00
elif self . mode == ' SUFFIXES ' :
suffix_list = os . getenv ( ' SUFFIXES ' )
if not suffix_list :
self . report ( { ' ERROR ' } , ' No suffix preset to load from project environnement ' )
return { ' CANCELLED ' }
2022-10-09 00:28:14 +02:00
set_namespace_env ( ' SUFFIXES ' , prefs . suffixes )
2021-09-07 15:41:54 +02:00
return { ' FINISHED ' }
2021-01-10 16:47:17 +01:00
### --- REGISTER ---
# class GP_PG_ToolsSettings(bpy.types.PropertyGroup) :
# autotint_offset = bpy.props.IntProperty(name="Tint hue offset", description="offset the tint by this value for better color", default=0, min=-5000, max=5000, soft_min=-999, soft_max=999, step=1)#, subtype='PERCENTAGE'
classes = (
2022-02-22 11:29:31 +01:00
GPTB_set_env_settings ,
GPTB_prefs ,
2021-01-10 16:47:17 +01:00
)
2022-02-22 11:29:31 +01:00
addon_modules = (
OP_helpers ,
2022-10-13 00:09:12 +02:00
OP_pseudo_tint ,
2022-02-22 11:29:31 +01:00
OP_keyframe_jump ,
OP_file_checker ,
OP_breakdowner ,
OP_temp_cutter ,
GP_colorize ,
OP_playblast_bg ,
OP_playblast ,
OP_palettes ,
OP_palettes_linker ,
OP_brushes ,
OP_cursor_snap_canvas ,
OP_copy_paste ,
OP_flat_reproject ,
OP_realign ,
OP_depth_move ,
OP_key_duplicate_send ,
2022-10-13 00:09:12 +02:00
OP_layer_namespace ,
2022-02-22 11:29:31 +01:00
OP_layer_manager ,
OP_material_picker ,
OP_git_update ,
OP_layer_picker ,
OP_layer_nav ,
2022-11-04 18:45:37 +01:00
OP_follow_curve ,
2022-03-24 18:25:56 +01:00
# OP_eraser_brush,
# TOOL_eraser_brush, # experimental eraser brush
2022-02-22 11:29:31 +01:00
handler_draw_cam ,
UI_tools ,
keymaps ,
)
2021-01-10 16:47:17 +01:00
def register ( ) :
2022-10-13 00:09:12 +02:00
# Register property group first
properties . register ( )
2021-01-10 16:47:17 +01:00
for cls in classes :
bpy . utils . register_class ( cls )
2022-02-22 11:29:31 +01:00
for mod in addon_modules :
mod . register ( )
2021-01-10 16:47:17 +01:00
bpy . types . Scene . gptoolprops = bpy . props . PointerProperty ( type = GP_PG_ToolsSettings )
2021-06-23 16:30:30 +02:00
set_env_properties ( )
## add handler (if option is on)
2022-01-23 16:27:30 +01:00
prefs = get_addon_prefs ( )
if prefs . use_relative_remap_on_save :
2021-03-07 00:39:32 +01:00
if not ' remap_relative ' in [ hand . __name__ for hand in bpy . app . handlers . save_pre ] :
bpy . app . handlers . save_pre . append ( remap_relative )
2022-01-23 16:27:30 +01:00
2022-10-08 01:15:34 +02:00
## Change a variable in prefs if a '.git is detected'
2022-01-23 16:27:30 +01:00
prefs . is_git_repo = ( Path ( __file__ ) . parent / ' .git ' ) . exists ( )
prefs . has_git = bool ( which ( ' git ' ) )
2021-01-10 16:47:17 +01:00
def unregister ( ) :
2021-03-07 00:39:32 +01:00
if ' remap_relative ' in [ hand . __name__ for hand in bpy . app . handlers . save_pre ] :
bpy . app . handlers . save_pre . remove ( remap_relative )
2021-01-10 16:47:17 +01:00
2022-02-22 11:29:31 +01:00
for mod in reversed ( addon_modules ) :
mod . unregister ( )
2021-01-10 16:47:17 +01:00
for cls in reversed ( classes ) :
bpy . utils . unregister_class ( cls )
2022-10-13 00:09:12 +02:00
properties . unregister ( )
2022-02-22 11:29:31 +01:00
2021-01-10 16:47:17 +01:00
del bpy . types . Scene . gptoolprops
if __name__ == " __main__ " :
register ( )