2021-01-10 16:47:17 +01:00
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
bl_info = {
2021-01-10 19:12:09 +01:00
" name " : " gp toolbox " ,
2021-01-10 16:47:17 +01:00
" description " : " Set of tools for Grease Pencil in animation production " ,
" author " : " Samuel Bernou " ,
" version " : ( 0 , 9 , 1 ) ,
" blender " : ( 2 , 91 , 0 ) ,
" location " : " sidebar (N menu) > Gpencil > Toolbox / Gpencil properties " ,
" warning " : " " ,
" doc_url " : " https://gitlab.com/autour-de-minuit/blender/gp_toolbox " ,
" category " : " 3D View " ,
}
from . import addon_updater_ops
from . utils import *
from . functions import *
## GMIC
from . GP_guided_colorize import GP_colorize
## direct tools
from . import OP_breakdowner
from . import OP_temp_cutter
from . import OP_canvas_rotate
from . import OP_playblast_bg
from . import OP_playblast
from . import OP_helpers
from . import OP_box_deform
from . import OP_cursor_snap_canvas
from . import OP_palettes
from . import OP_file_checker
from . import OP_render
from . import OP_copy_paste
from . import keymaps
from . OP_pseudo_tint import GPT_OT_auto_tint_gp_layers
from . import UI_tools
from . properties import GP_PG_ToolsSettings
from bpy . props import ( FloatProperty ,
BoolProperty ,
EnumProperty ,
StringProperty ,
IntProperty )
import bpy
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()
class GPTB_prefs ( bpy . types . AddonPreferences ) :
bl_idname = __name__
## tabs
pref_tabs : bpy . props . EnumProperty (
items = ( ( ' PREF ' , " Preferences " , " Change some preferences of the modal " ) ,
( ' MAN_OPS ' , " Operator " , " Operator to add Manually " ) ,
# ('TUTO', "Tutorial", "How to use the tool"),
# ('GMIC', "Gmic color", "Options to use gmic to colorize"),
( ' UPDATE ' , " Update " , " Check and apply updates " ) ,
# ('KEYMAP', "Keymap", "customise the default keymap"),
) ,
default = ' PREF ' )
## addon pref updater props
auto_check_update : BoolProperty (
name = " Auto-check for Update " ,
description = " If enabled, auto-check for updates using an interval " ,
default = False ,
)
updater_intrval_months : IntProperty (
name = ' Months ' ,
description = " Number of months between checking for updates " ,
default = 0 ,
min = 0
)
updater_intrval_days : IntProperty (
name = ' Days ' ,
description = " Number of days between checking for updates " ,
default = 7 ,
min = 0 ,
max = 31
)
updater_intrval_hours : IntProperty (
name = ' Hours ' ,
description = " Number of hours between checking for updates " ,
default = 0 ,
min = 0 ,
max = 23
)
updater_intrval_minutes : IntProperty (
name = ' Minutes ' ,
description = " Number of minutes between checking for updates " ,
default = 0 ,
min = 0 ,
max = 59
)
## addon prefs
## Project preferences
# subtype (string) – Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD', 'NONE'].
## fps
fps : IntProperty (
name = ' Frame Rate ' ,
description = " Fps of the project, Used to conform the file when you use Check file operator " ,
default = 25 ,
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 ' )
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 ' )
palette_path : StringProperty (
name = " Palettes directory " ,
description = " Path to palette containing palette.json files to save and load " ,
default = " // " , maxlen = 0 , subtype = ' DIR_PATH ' ) #, update = set_palette_path
## 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 ,
)
## Canvas rotate
canvas_use_shortcut : BoolProperty (
name = " Use Default Shortcut " ,
description = " Use default shortcut: mouse double-click + modifier " ,
default = True )
mouse_click : EnumProperty (
name = " Mouse button " , description = " click on right/left/middle mouse button in combination with a modifier to trigger alignement " ,
default = ' RIGHTMOUSE ' ,
items = (
( ' RIGHTMOUSE ' , ' Right click ' , ' Use click on Right mouse button ' , ' MOUSE_RMB ' , 0 ) ,
( ' LEFTMOUSE ' , ' Left click ' , ' Use click on Left mouse button ' , ' MOUSE_LMB ' , 1 ) ,
( ' MIDDLEMOUSE ' , ' Mid click ' , ' Use click on Mid mouse button ' , ' MOUSE_MMB ' , 2 ) ,
) )
use_shift : BoolProperty (
name = " combine with shift " ,
description = " add shift combined with double click to trigger alignement " ,
default = False )
use_alt : BoolProperty (
name = " combine with alt " ,
description = " add alt combined with double click to trigger alignement (default) " ,
default = True )
use_ctrl : BoolProperty (
name = " combine with ctrl " ,
description = " add ctrl combined with double click to trigger alignement " ,
default = True )
## default active tool to use
select_active_tool : EnumProperty (
name = " Default selection tool " , description = " Active tool to set when launching check fix scene " ,
default = ' builtin.select_lasso ' ,
items = (
( ' none ' , ' Dont change ' , ' Let the current active tool without change ' , 0 ) , #'MOUSE_RMB'
( ' builtin.select ' , ' Select tweak ' , ' Use active select tweak active tool ' , 1 ) , #'MOUSE_RMB'
( ' builtin.select_box ' , ' Select box ' , ' Use active select box active tool ' , 2 ) , #'MOUSE_LMB'
( ' builtin.select_circle ' , ' Select circle ' , ' Use active select circle active tool ' , 3 ) , #'MOUSE_MMB'
( ' builtin.select_lasso ' , ' Select lasso ' , ' Use active select lasso active tool ' , 4 ) , #'MOUSE_MMB'
) )
## 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
)
## Temp cutter
# temp_cutter_use_shortcut: BoolProperty(
# name = "Use temp cutter Shortcut",
# description = "Auto assign shortcut for temp_cutter",
# default = True)
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 = ' Random color options: ' )
box . prop ( self , ' separator ' )
box = layout . box ( )
box . label ( text = ' Project settings ' )
## Render
# box.label(text='Render option:')
box . prop ( self , ' fps ' )
row = box . row ( align = True )
row . label ( text = ' Render resolution ' )
row . prop ( self , ' render_res_x ' , text = ' X ' )
row . prop ( self , ' render_res_y ' , text = ' Y ' )
## Palette
box . label ( text = ' Palette library folder: ' )
box . prop ( self , ' palette_path ' )
## render output
## ?? maybe add an option for absolute path (not really usefull in prod) ??
box . prop ( self , ' output_path ' )
### 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 ' )
# box.separator()## Canvas
box = layout . box ( )
box . label ( text = ' Canvas rotate options: ' )
box . prop ( self , " canvas_use_shortcut " , text = ' Bind shortcuts ' )
if self . canvas_use_shortcut :
row = box . row ( )
row . label ( text = " After changes, use the Bind/Rebind button " ) #icon=""
row . operator ( " prefs.rebind_shortcut " , text = ' Bind/Rebind shortcuts ' , icon = ' FILE_REFRESH ' ) #EVENT_SPACEKEY
row = box . row ( align = True )
row . prop ( self , " use_ctrl " , text = ' Ctrl ' ) #, expand=True
row . prop ( self , " use_alt " , text = ' Alt ' ) #, expand=True
row . prop ( self , " use_shift " , text = ' Shift ' ) #, expand=True
row . prop ( self , " mouse_click " , text = ' ' ) #expand=True
if not self . use_ctrl and not self . use_alt and not self . use_shift :
box . label ( text = " Choose at least one modifier to combine with click (default: Ctrl+Alt) " , icon = " ERROR " ) # INFO
else :
box . label ( text = " No hotkey has been set automatically. Following operators needs to be set manually: " , icon = " ERROR " )
box . label ( text = " view3d.rotate_canvas " )
# TODO get that off once proper register update from properties
if self . canvas_use_shortcut :
OP_canvas_rotate . register_keymaps ( )
else :
OP_canvas_rotate . unregister_keymaps ( )
## Active tool
box = layout . box ( )
box . label ( text = ' Autofix check button options: ' )
box . prop ( self , " select_active_tool " , icon = ' RESTRICT_SELECT_OFF ' )
box . prop ( self , " render_obj_exclusion " , icon = ' FILTER ' ) #
if self . pref_tabs == ' MAN_OPS ' :
# layout.separator()## notes
# layout.label(text='Notes:')
layout . label ( text = ' Following operators ID have to be set manually : ' )
## 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 ' )
## 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 ' )
if self . pref_tabs == ' UPDATE ' :
addon_updater_ops . update_settings_ui ( self , context )
### --- 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'
@persistent
def remap_relative ( dummy ) :
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 )
classes = (
GPTB_prefs ,
GP_PG_ToolsSettings ,
GPT_OT_auto_tint_gp_layers ,
)
# register, unregister = bpy.utils.register_classes_factory(classes)
def register ( ) :
addon_updater_ops . register ( bl_info )
for cls in classes :
bpy . utils . register_class ( cls )
OP_box_deform . register ( )
OP_helpers . register ( )
OP_file_checker . register ( )
OP_breakdowner . register ( )
OP_temp_cutter . register ( )
GP_colorize . register ( ) ## GP_guided_colorize.
OP_playblast_bg . register ( )
OP_playblast . register ( )
OP_palettes . register ( )
OP_canvas_rotate . register ( )
OP_cursor_snap_canvas . register ( )
OP_render . register ( )
OP_copy_paste . register ( )
UI_tools . register ( )
keymaps . register ( )
bpy . types . Scene . gptoolprops = bpy . props . PointerProperty ( type = GP_PG_ToolsSettings )
bpy . app . handlers . save_pre . append ( remap_relative )
def unregister ( ) :
bpy . app . handlers . save_pre . remove ( remap_relative )
keymaps . unregister ( )
addon_updater_ops . unregister ( )
for cls in reversed ( classes ) :
bpy . utils . unregister_class ( cls )
UI_tools . unregister ( )
OP_copy_paste . unregister ( )
OP_render . unregister ( )
OP_cursor_snap_canvas . unregister ( )
OP_canvas_rotate . unregister ( )
OP_palettes . unregister ( )
OP_file_checker . unregister ( )
OP_helpers . unregister ( )
OP_breakdowner . unregister ( )
OP_temp_cutter . unregister ( )
GP_colorize . unregister ( ) ## GP_guided_colorize.
OP_playblast_bg . unregister ( )
OP_playblast . unregister ( )
OP_box_deform . unregister ( )
del bpy . types . Scene . gptoolprops
if __name__ == " __main__ " :
register ( )