stripped obsolete features and compacted UI

1.7.0

- remove: Obsolete operators and panels
  - Remove "line closer" panel as it's been a native tool for a while in 2.9x (stop register of `GP_guided_colorize > OP_line_closer`)
  - Remove "Render" subpanel, obsolete and not adapted to production
- ui: clean and refactor
  - Gp clipboard panel and aimation Manager subpanel layout to aligned columns (gain space)
  - add `GP` on each panel name for wuick eye search
  - follow cursor now in animation manager subpanel (should be in an extra menu or removed in the end)
gpv2
Pullusb 2021-10-20 13:56:01 +02:00
parent 8b838b52ca
commit f7e8dce0ff
7 changed files with 147 additions and 614 deletions

View File

@ -1,5 +1,16 @@
# Changelog # Changelog
1.7.0
- removed: Obsolete operators and panels
- Remove "line closer" panel as it's been a native tool for a while in 2.9x (stop register of `GP_guided_colorize > OP_line_closer`)
- Remove "Render" subpanel, obsolete and not adapted to production
- ui: clean and refactor
- Gp clipboard panel and aimation Manager subpanel layout to aligned columns (gain space)
- add `GP` on each panel name for wuick eye search
- follow cursor now in animation manager subpanel (should be in an extra menu or removed in the end)
1.6.9 1.6.9
- change: material picker (`S` and `Alt+S`) quick trigger, cahnge is only triggered if ley is pressed less than 200ms - change: material picker (`S` and `Alt+S`) quick trigger, cahnge is only triggered if ley is pressed less than 200ms
@ -139,29 +150,29 @@
- feat: show main cam frame when in draw_cam - feat: show main cam frame when in draw_cam
1.3.2: 1.3.2
- change: disable manip cam name drawing - change: disable manip cam name drawing
- code: add initial support for main cam frame draw within camera view - code: add initial support for main cam frame draw within camera view
1.3.1: 1.3.1
- fix: native refresh error that rarely happen that doesn't completely refresh the scene on keyframe jump. - fix: native refresh error that rarely happen that doesn't completely refresh the scene on keyframe jump.
- Use a double frame change to ensure refresh. - Use a double frame change to ensure refresh.
1.3.0: 1.3.0
- feat: new duplicate send to layer feaure - `ctrl + shift + D` in GP dopesheet - feat: new duplicate send to layer feaure - `ctrl + shift + D` in GP dopesheet
1.2.2: 1.2.2
- fix: realign anim return error - fix: realign anim return error
1.2.1: 1.2.1
- fix: Breakdowner initial error check - fix: Breakdowner initial error check
1.2.0: 1.2.0
- feat: New depth move operator that handle both perspective and orthographic cam - feat: New depth move operator that handle both perspective and orthographic cam
- feat: Realign, added drawing plane checkbox to autoset to Front after realign - feat: Realign, added drawing plane checkbox to autoset to Front after realign
@ -170,67 +181,67 @@
- doc: Added changelog file (moved list from readme) - doc: Added changelog file (moved list from readme)
- doc: relative link to changelog and FR_readme in main readme - doc: relative link to changelog and FR_readme in main readme
1.1.0: 1.1.0
- Important change : Remap relative is now disabled by default in addon preferences - Important change : Remap relative is now disabled by default in addon preferences
- feat: Add realign operator in sidebar with reproject as true by default - feat: Add realign operator in sidebar with reproject as true by default
- UI: Batch reproject all frames is now in menus. Same places as native reproject - UI: Batch reproject all frames is now in menus. Same places as native reproject
1.0.9: 1.0.9
- feat: Reproject all frames operator - feat: Reproject all frames operator
1.0.8: 1.0.8
- feat: Keyframe jump filter added in UI to change general behavior. Keymap own jump filter can override this new global settings if specified - feat: Keyframe jump filter added in UI to change general behavior. Keymap own jump filter can override this new global settings if specified
1.0.7: 1.0.7
- feat: Keyframe jump filter by type. User can now choose if the shortcut should jump on a specific keyframe type (All by default) - feat: Keyframe jump filter by type. User can now choose if the shortcut should jump on a specific keyframe type (All by default)
1.0.5: 1.0.5
- GP copy-paste : Pasted stroke are now selected (allow to use it to quickly rip/split strokes with cut/paste on the same layer) - GP copy-paste : Pasted stroke are now selected (allow to use it to quickly rip/split strokes with cut/paste on the same layer)
1.0.4: 1.0.4
- UI: Better cam ref exposition in Toolbox panel - UI: Better cam ref exposition in Toolbox panel
- Access to opacity - Access to opacity
- merge activation bool with source type icon - merge activation bool with source type icon
- feat: Added a clear active frame operator (`gp.clear_active_frame` to add manually in keymaps) - feat: Added a clear active frame operator (`gp.clear_active_frame` to add manually in keymaps)
1.0.3: 1.0.3
- feat: add "Append Materials To Selected" to material submenu. Append materials to other selected GP objects if there aren't there. - feat: add "Append Materials To Selected" to material submenu. Append materials to other selected GP objects if there aren't there.
1.0.2: 1.0.2
- pref: Added option to disable always remap relative on save in addon-preference - pref: Added option to disable always remap relative on save in addon-preference
1.0.1: 1.0.1
- fix: copy paste problems - fix: copy paste problems
- Get points uv_properties (used for brushed points) - Get points uv_properties (used for brushed points)
- Trigger an update on each pasted strokes, recalculate badly drawn uv and fills (works in 2.93+) - Trigger an update on each pasted strokes, recalculate badly drawn uv and fills (works in 2.93+)
1.0.0: 1.0.0
- Compatible with official grease pencil tools - Compatible with official grease pencil tools
- removed box deform and rotate canvas that existed in other - removed box deform and rotate canvas that existed in other
0.9.3: 0.9.3
- feat: keyframe jump keys are now auto-binded - feat: keyframe jump keys are now auto-binded
- UI: added keyframe jump customisation in addon pref - UI: added keyframe jump customisation in addon pref
- code: split keyframe jump in a separate file with his new key updater - code: split keyframe jump in a separate file with his new key updater
0.9.2: 0.9.2
- doc: Correct download link (important, bugged the addon install) + update - doc: Correct download link (important, bugged the addon install) + update
- code: added tracker url - code: added tracker url
- updater: remove updater temp file, reset minimum version, turn off verbose mode - updater: remove updater temp file, reset minimum version, turn off verbose mode
0.9.1: 0.9.1
- Public release - Public release
- prefs: added fps as part of project settings - prefs: added fps as part of project settings
@ -240,38 +251,38 @@
- doc: Added fully-detailed french readme - doc: Added fully-detailed french readme
0.8.0: 0.8.0
- feat: Added background_rendering playblast, derivating from Tonton's playblaster - feat: Added background_rendering playblast, derivating from Tonton's playblaster
- stripped associated properties from properties.py and passed as wm props. - stripped associated properties from properties.py and passed as wm props.
0.7.2: 0.7.2
- fix: Palette importer bug - fix: Palette importer bug
0.7.0: 0.7.0
- feat: auto create empty frame on color layer - feat: auto create empty frame on color layer
0.6.3: 0.6.3
- shortcut: added 1,2,3 to change sculpt mask mode (like native edit mode shortcut) - shortcut: added 1,2,3 to change sculpt mask mode (like native edit mode shortcut)
0.6.2: 0.6.2
- feat: colorisation, Option to change stop lines length - feat: colorisation, Option to change stop lines length
- Change behavior of `cursor_snap` ops when a non-GP object is selected to mode: `surface project` - Change behavior of `cursor_snap` ops when a non-GP object is selected to mode: `surface project`
- Minor refactor for submodule register - Minor refactor for submodule register
0.6.1: 0.6.1
- feat: render objects grouped, one anim render with all ticked object using manual output name - feat: render objects grouped, one anim render with all ticked object using manual output name
0.6.0: 0.6.0
- feat: Include GP clipoard's "In place" custom cut/copy/paste using OS clipboard - feat: Include GP clipoard's "In place" custom cut/copy/paste using OS clipboard
0.5.9: 0.5.9
- feat: render exporter - feat: render exporter
- Render a selection of GP object isolated from the rest - Render a selection of GP object isolated from the rest
@ -281,21 +292,21 @@
- check file: set onion skin keyframe filter to 'All_type' on all GP datablock - check file: set onion skin keyframe filter to 'All_type' on all GP datablock
- check file: set scene resolution to settings in prefs (default 2048x1080) - check file: set scene resolution to settings in prefs (default 2048x1080)
0.5.8: 0.5.8
- feat: GP material append on active object from single blend file - feat: GP material append on active object from single blend file
0.5.7: 0.5.7
- Added warning message for cursor snapping - Added warning message for cursor snapping
0.5.5 - 0.5.6: 0.5.6
- check file: added check for placement an projection mode for Gpencil. - check file: added check for placement an projection mode for Gpencil.
- add a slider to change edit_lines_opacity globally for all GP data at once - add a slider to change edit_lines_opacity globally for all GP data at once
- check file: auto-check additive drawing (to avoid empty frame with "only selected channel" in Dopesheet) - check file: auto-check additive drawing (to avoid empty frame with "only selected channel" in Dopesheet)
0.5.4: 0.5.4
- feat: anim manager in his own GP_toolbox submenu: - feat: anim manager in his own GP_toolbox submenu:
- button to list disabled anim (allow to quickly check state of the scene) - button to list disabled anim (allow to quickly check state of the scene)
@ -303,19 +314,19 @@
- shift clic to target selection only - shift clic to target selection only
- check file: added disabled fcurved counter alert with detail in console - check file: added disabled fcurved counter alert with detail in console
0.5.3: 0.5.3
- fix: broken obj cam (add custom prop on objcam to track wich was main cam) - fix: broken obj cam (add custom prop on objcam to track wich was main cam)
- check file option: change select active tool (choice added in addon preferences) - check file option: change select active tool (choice added in addon preferences)
0.5.2: 0.5.2
- Revert back obj_cam operator for following object (native lock view follow only translation) - Revert back obj_cam operator for following object (native lock view follow only translation)
- Changed method for canvas rotation to more robust rotate axis. - Changed method for canvas rotation to more robust rotate axis.
- Add operators on link checker to open containing folder/file of link - Add operators on link checker to open containing folder/file of link
- Refactor: file checkers in their own file - Refactor: file checkers in their own file
0.5.1: 0.5.1
- fix: error when empty material slot on GP object. - fix: error when empty material slot on GP object.
- fix: cursor snap on GP canvas when GP is parented - fix: cursor snap on GP canvas when GP is parented
@ -330,11 +341,11 @@
- set show slider and sync range - set show slider and sync range
- set fps to 24 - set fps to 24
0.4.6: 0.4.6
- feat: basic Palette manager with base material check and warning - feat: basic Palette manager with base material check and warning
0.4.5: 0.4.5
- open blender config folder from addon preference - open blender config folder from addon preference
- fix: obj cam parent on selected object - fix: obj cam parent on selected object
@ -343,29 +354,29 @@
- camview: potential bug when cam is parented with some specific angle (could not reproduce) - camview: potential bug when cam is parented with some specific angle (could not reproduce)
0.4.4: 0.4.4
- feat: added cursor follow handlers and UI toggle - feat: added cursor follow handlers and UI toggle
0.4.3: 0.4.3
- change playblast out to 'images' and add playblast as name prefix - change playblast out to 'images' and add playblast as name prefix
0.4.2: 0.4.2
- feat: GP canvas cursor snap wiht new `view3d.cusor_snap` operator - feat: GP canvas cursor snap wiht new `view3d.cusor_snap` operator
- fix: canvas rotate works with parented camera ! - fix: canvas rotate works with parented camera !
- wip: added an attmpt to replicate camera rotate modal with view matrix but no luck. - wip: added an attmpt to replicate camera rotate modal with view matrix but no luck.
0.4.1: 0.4.1
- feat: Alternative cameras: parent to main cam (roll without affecting main cam), parent to active object at current view (follow current Grease pencil object) - feat: Alternative cameras: parent to main cam (roll without affecting main cam), parent to active object at current view (follow current Grease pencil object)
0.4.0: 0.4.0
- Added a standalone working version of box_deform (stripped preferences keeping only best configuration with autoswap) - Added a standalone working version of box_deform (stripped preferences keeping only best configuration with autoswap)
0.3.8: 0.3.8
- UI: expose onion skin in interface - UI: expose onion skin in interface
- UI: expose autolock in interface - UI: expose autolock in interface
@ -373,47 +384,47 @@
- code: refactor, pushed most of class register in their owner file - code: refactor, pushed most of class register in their owner file
- tool: tool to rename current or all grease pencil datablock with different name than container object - tool: tool to rename current or all grease pencil datablock with different name than container object
0.3.7: 0.3.7
- UI: new interface with tabs for addon preferences - UI: new interface with tabs for addon preferences
- UI: possible to disable color panel from preference (might be deleted if unusable) - UI: possible to disable color panel from preference (might be deleted if unusable)
- docs: change readme changelog format and correct doc - docs: change readme changelog format and correct doc
0.3.6: 0.3.6
- UI: Stoplines : add a button for quickly set stoplines visibility. - UI: Stoplines : add a button for quickly set stoplines visibility.
0.3.5: 0.3.5
- Fix : No more camera rotation undo when ctrl+Z on next stroke (canvas rotate push and undo) - Fix : No more camera rotation undo when ctrl+Z on next stroke (canvas rotate push and undo)
- Fix: Enter key added to valid object-breakdown modal. - Fix: Enter key added to valid object-breakdown modal.
0.3.3: 0.3.3
- version 1 beta (stable) of line gap closing tools for better bucket fill tool performance with UI - version 1 beta (stable) of line gap closing tools for better bucket fill tool performance with UI
0.3.3: 0.3.3
- version 1 beta of gmic colorize - version 1 beta of gmic colorize
- variant of `screen.gp_keyframe_jump` through keymap seetings - variant of `screen.gp_keyframe_jump` through keymap seetings
0.3.0: 0.3.0
- new homemade [breakdowner operator for object](https://blenderartists.org/t/pose-mode-animation-tools-for-object-mode/1221322) mode with auto keymap : Shift + E - new homemade [breakdowner operator for object](https://blenderartists.org/t/pose-mode-animation-tools-for-object-mode/1221322) mode with auto keymap : Shift + E
- GP cutter shortcut ops to map with `wm.temp_cutter` (with "Any" as press mode) or `wm.sticky_cutter` (Modal sticky-key version) - GP cutter shortcut ops to map with `wm.temp_cutter` (with "Any" as press mode) or `wm.sticky_cutter` (Modal sticky-key version)
0.2.3: 0.2.3
- add operator to `screen.gp_keyframe_jump` - add operator to `screen.gp_keyframe_jump`
- add shortcut to rotate canvas - add shortcut to rotate canvas
- fix duplicate class - fix duplicate class
0.2.2: 0.2.2
- separated props resolution_percentage parameter - separated props resolution_percentage parameter
- playblast options for launching folder and opening folder - playblast options for launching folder and opening folder
0.2.1: 0.2.1
- playblast feature - playblast feature
- Button to go zoom 100% or fit screen - Button to go zoom 100% or fit screen
@ -421,22 +432,22 @@
- Fix reference panel : works with video and display in a box layout. - Fix reference panel : works with video and display in a box layout.
- close pseudo-color panel by default (plan to move it to Gpencil tab) - close pseudo-color panel by default (plan to move it to Gpencil tab)
0.2.0: 0.2.0
- UI: Toggle camera background images from Toolbox panel - UI: Toggle camera background images from Toolbox panel
- UI: quick access to passepartout - UI: quick access to passepartout
- Feature: option to use namespace for pseudo color - Feature: option to use namespace for pseudo color
0.1.5: 0.1.5
- added CGC-auto-updater - added CGC-auto-updater
0.1.3: 0.1.3
- flip cam x - flip cam x
- inital stage of overlay toggle (need pref/multiple pref) - inital stage of overlay toggle (need pref/multiple pref)
0.1.2: 0.1.2
- subpanel of GP data (instead of direct append) - subpanel of GP data (instead of direct append)
- initial commit with GP pseudo color - initial commit with GP pseudo color

View File

@ -13,7 +13,7 @@
import bpy import bpy
from . import OP_line_closer # from . import OP_line_closer
from . import OP_create_empty_frames from . import OP_create_empty_frames
@ -45,11 +45,11 @@ def register():
for cls in classes: for cls in classes:
bpy.utils.register_class(cls) bpy.utils.register_class(cls)
OP_create_empty_frames.register() OP_create_empty_frames.register()
OP_line_closer.register() # OP_line_closer.register()
bpy.types.Scene.gpcolor_props = bpy.props.PointerProperty(type = GPCOLOR_PG_settings) bpy.types.Scene.gpcolor_props = bpy.props.PointerProperty(type = GPCOLOR_PG_settings)
def unregister(): def unregister():
OP_line_closer.unregister() # OP_line_closer.unregister()
OP_create_empty_frames.unregister() OP_create_empty_frames.unregister()
for cls in reversed(classes): for cls in reversed(classes):
bpy.utils.unregister_class(cls) bpy.utils.unregister_class(cls)

View File

@ -637,13 +637,16 @@ class GPCLIP_PT_clipboard_ui(bpy.types.Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
row = layout.row(align=True)
col = layout.column(align=True)
row = col.row(align=True)
row.operator('gp.copy_strokes', text='Copy strokes', icon='COPYDOWN') row.operator('gp.copy_strokes', text='Copy strokes', icon='COPYDOWN')
row.operator('gp.cut_strokes', text='Cut strokes', icon='PASTEFLIPUP') row.operator('gp.cut_strokes', text='Cut strokes', icon='PASTEFLIPUP')
layout.operator('gp.paste_strokes', text='Paste strokes', icon='PASTEDOWN') col.operator('gp.paste_strokes', text='Paste strokes', icon='PASTEDOWN')
layout.separator() # layout.separator()
layout.operator('gp.copy_multi_strokes', text='Copy layers', icon='COPYDOWN') col = layout.column(align=True)
layout.operator('gp.paste_multi_strokes', text='Paste layers', icon='PASTEDOWN') col.operator('gp.copy_multi_strokes', text='Copy layers', icon='COPYDOWN')
col.operator('gp.paste_multi_strokes', text='Paste layers', icon='PASTEDOWN')
###---TEST zone ###---TEST zone

View File

@ -1,482 +0,0 @@
import bpy
import os
from os import listdir, scandir
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
import re, fnmatch, glob
from pathlib import Path
from time import strftime
C = bpy.context
D = bpy.data
from .utils import open_file, open_folder, get_addon_prefs
### render the png sequences
def initial_render_checks(context=None):
if not context:
context=bpy.context
if not bpy.data.is_saved:
return "File is not saved, render cancelled"
cam = context.scene.camera
if not cam:
return "No active Camera"
if cam.name == 'draw_cam':
if not cam.parent:
return "Camera is draw_cam but has no parent cam to render from..."
context.scene.camera = cam.parent
if cam.name == 'obj_cam':
if not cam.get('maincam_name'):
return "Cannot found main camera from obj_cam. Set main camera manually"
main_cam = context.scene.objects.get(cam['maincam_name'])
if not main_cam:
return f"Main camera not found with name: {cam['main_cam']}"
context.scene.camera = main_cam
return
exclude = (
### add lines here to exclude specific attribute
'bl_rna', 'identifier','name_property','rna_type','properties', 'compare', 'to_string',#basic
)
"""
rd_keep = [
"resolution_percentage",
"resolution_x",
"resolution_y",
"filepath",
"use_stamp",
"stamp_font_size",
]
im_keep = [
'file_format',
'color_mode',
'quality',
'compression',
]
ff_keep = [
'codec',
'format',
'constant_rate_factor',
'ffmpeg_preset',
'gopsize',
'audio_codec',
'audio_bitrate',
]
"""
def render_with_restore():
class RenderFileRestorer:
rd = bpy.context.scene.render
im = rd.image_settings
ff = rd.ffmpeg
# ffmpeg (ff) need to be before image_settings(im) in list
# otherwise __exit__ may try to restore settings of image mode in video mode !
# ex : "RGBA" not found in ('BW', 'RGB') (will still not stop thx to try block)
zones = [rd, ff, im]
obviz = {}
# layviz = []
# matviz = []
closeline = False
val_dic = {}
cam = bpy.context.scene.camera
enter_context = None
def __enter__(self):
self.enter_context = bpy.context
## store attribute of data_path in self.zones list.
for data_path in self.zones:
self.val_dic[data_path] = {}
for attr in dir(data_path):#iterate in attribute of given datapath
if attr not in exclude and not attr.startswith('__') and not callable(getattr(data_path, attr)) and not data_path.is_property_readonly(attr):
self.val_dic[data_path][attr] = getattr(data_path, attr)
# cam
if self.cam and self.cam.name == 'draw_cam':
if self.cam.parent:
bpy.context.scene.camera = self.cam.parent
#case of obj cam
if self.cam.name == 'obj_cam':
bpy.context.scene.camera = bpy.context.scene.objects.get(self.cam['main_cam'])
for ob in bpy.context.scene.objects:
self.obviz[ob.name] = ob.hide_render
close_mat = bpy.data.materials.get('closeline')
if close_mat and not close_mat.grease_pencil.hide:
close_mat.grease_pencil.hide = True
self.closeline = True
# for gpo in bpy.context.scene.objects:
# if gpo.type != 'GPENCIL':
# continue
# if not gpo.materials.get('closeline'):
# continue
# self.closelines[gpo] = gpo.materials['closeline'].hide_render
def __exit__(self, type, value, traceback):
## reset header text
# self.enter_context.area.header_text_set(None)
### maybe keep render settings for custom output with right mode
"""
## restore attribute from self.zones list
for data_path, prop_dic in self.val_dic.items():
for attr, val in prop_dic.ietms():
try:
setattr(data_path, attr, val)
except Exception as e:
print(f"/!\ Impossible to re-assign: {attr} = {val}")
print(e)
"""
if self.cam:
bpy.context.scene.camera = self.cam
for obname, val in self.obviz.items():
bpy.context.scene.objects[obname].hide_render = val
if self.closeline:
close_mat = bpy.data.materials.get('closeline')
if close_mat:
close_mat.grease_pencil.hide = False
return RenderFileRestorer()
def set_render_settings():
prefs = get_addon_prefs()
rd = bpy.context.scene.render
rd.use_sequencer = False
rd.use_compositing = False
rd.use_overwrite = True
rd.image_settings.file_format = 'PNG'
rd.image_settings.color_mode = 'RGBA'
rd.image_settings.color_depth = '16'
rd.image_settings.compression = 80 #maybe up the compression a bit...
rd.resolution_percentage = 100
rd.resolution_x, rd.resolution_y = prefs.render_res_x, prefs.render_res_y
rd.use_stamp = False
rd.film_transparent = True
def render_invididually(context, render_list):
'''Receive a list of object to render individually isolated'''
prefs = get_addon_prefs()
scn = context.scene
rd = scn.render
error_list = []
with render_with_restore():
set_render_settings()
# rd.filepath = join(dirname(bpy.data.filepath), basename(bpy.data.filepath))
# rd.frame_path(frame=0, preview=0, view="_sauce")## give absolute render filepath with some suffix
## set filepath
blend = Path(bpy.data.filepath)
### render by object in list
for obname in render_list:
the_obj = scn.objects.get(obname)
if not the_obj:
error_list.append(f'! Could not found {obname} in scene, skipped !')
continue
## Kill renderability of all
for o in scn.objects:
o.hide_render = True
the_obj.hide_render = False
# f'{blend.stem}_'
# fp = blend.parents[1] / "compo" / "base" / obname / (obname+'_')
fp = (blend.parent / prefs.output_path.lstrip(r'\/')).resolve() / obname / (obname+'_')
rd.filepath = str(fp)
# Freeze so impossible to display advance
# context.area.header_text_set(f'rendering > {obname} ...')
### render
# bpy.ops.render.render_wrap(use_view=viewport)
bpy.ops.render.render(animation=True)
# print("render Done :", fp)#Dbg
return error_list
def render_grouped(context, render_list):
'''Receive a list of object to render grouped'''
scn = context.scene
rd = scn.render
error_list = []
with render_with_restore():
set_render_settings()
## Kill renderability of all
for o in scn.objects:
o.hide_render = True
### show all object of the list
for obname in render_list:
the_obj = scn.objects.get(obname)
if not the_obj:
error_list.append(f'! Could not found {obname} in scene, skipped !')
continue
the_obj.hide_render = False
## Use current file path of setup output path else following :
blend = Path(bpy.data.filepath)
outname = context.scene.gptoolprops.name_for_current_render
# fp = blend.parents[1] / "compo" / "base" / outname / (outname+'_')
fp = (blend.parent / prefs.output_path.lstrip(r'\/')).resolve() / outname / (outname+'_')
rd.filepath = str(fp)
### render
# bpy.ops.render.render_wrap(use_view=viewport)
bpy.ops.render.render(animation=True)
# print("render Done :", fp)#Dbg
return error_list
class GPTRD_OT_render_anim(bpy.types.Operator):
bl_idname = "render.render_anim"
bl_label = "render anim"
bl_description = "Launch animation render"
bl_options = {"REGISTER"}
# use_view : bpy.props.BoolProperty(name='use_view', default=False)
to_render = []
mode : bpy.props.StringProperty(name="render mode",
description="change render mode for list rendering", default="INDIVIDUAL")
render_bool : bpy.props.BoolVectorProperty(name="render bools",
description="", default=tuple([True]*32), size=32, subtype='NONE')
def invoke(self, context, event):
# prefs = get_addons_prefs_and_set()
# if not prefs.local_folder:
# self.report({'ERROR'}, f'Project local folder is not specified in addon preferences')
# return {'CANCELLED'}
if self.mode == 'GROUP' and not context.scene.gptoolprops.name_for_current_render:
self.report({'ERROR'}, 'Need to set ouput name')
return {'CANCELLED'}
prefs = get_addon_prefs()
print('exclusions list ->', prefs.render_obj_exclusion)
exclusion_obj = [name.strip() for name in prefs.render_obj_exclusion.split(',')]
print('object exclusion list: ', exclusion_obj)
print('initial self.to_render: ', self.to_render)
self.to_render = []#reset
## check object to render with basic filter
for ob in context.scene.objects:
if ob.type != 'GPENCIL':
continue
if any(x in ob.name.lower() for x in exclusion_obj): #('old', 'rough', 'trash', 'test')
print('Skip', ob.name)
continue
self.to_render.append(ob.name)
if not self.to_render:
self.report({'ERROR'}, 'No GP to render')
return {'CANCELLED'}
## Reset at each render
# self.render_bool = tuple([True]*32)# reset all True
## disable for some name (ex: BG)
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, context):
layout = self.layout
layout.label(text='Tick objects to render')
for i, name in enumerate(self.to_render):
row = layout.row()
row.prop(self, 'render_bool', index = i, text = name)
# for i, set in enumerate(SETS):
# column.row().prop(context.scene.spritesheet, 'sets', index=i, text=set)
def execute(self, context):
prefs = get_addon_prefs()
err = initial_render_checks(context)
if err:
self.report({'ERROR'}, err)
return {"CANCELLED"}
render_list = []
for i, name in enumerate(self.to_render):
if self.render_bool[i]:
render_list.append(name)
if not render_list:
self.report({'ERROR'}, 'Nothing to render')
return {"CANCELLED"}
# self.report({'INFO'}, f'rendering {render_list}')#Dgb
# return {"FINISHED"}#Dgb
if self.mode == 'INDIVIDUAL':
errlist = render_invididually(context, render_list)
elif self.mode == 'GROUP':
errlist = render_grouped(context, render_list)
blend = Path(bpy.data.filepath)
# out = blend.parents[1] / "compo" / "base"
out = (blend.parent / prefs.output_path.lstrip(r'\/')).resolve()
if out.exists():
open_folder(str(out))
else:
errlist.append('No compo/base folder created')
if errlist:
self.report({'ERROR'}, '\n'.join(errlist))
return {"FINISHED"}
### ---- Setup render path
class GPTRD_OT_setup_render_path(bpy.types.Operator):
bl_idname = "render.setup_render_path"
bl_label = "Setup render"
bl_description = "Setup render settings for normal render of the current state\nHint: F12 to check one frame, ctrl+F12 to render animation"
bl_options = {"REGISTER"}
def execute(self, context):
#get name and check
prefs = get_addon_prefs()
outname = context.scene.gptoolprops.name_for_current_render
if not outname:
self.report({'ERROR'}, 'No output name has been set')
return {"CANCELLED"}
err = initial_render_checks(context)
if err:
self.report({'ERROR'}, err)
return {"CANCELLED"}
set_render_settings()
blend = Path(bpy.data.filepath)
# out = blend.parents[1] / "compo" / "base"
out = (blend.parent / prefs.output_path.lstrip(r'\/')).resolve()
fp = out / outname / (outname+'_')
context.scene.render.filepath = str(fp)
self.report({'INFO'}, f'output setup for "{outname}"')
return {"FINISHED"}
class GPTRD_OT_use_active_object_infos(bpy.types.Operator):
bl_idname = "render.use_active_object_name"
bl_label = "Use object Name"
bl_description = "Write active object name (active layer name with shift click on the button)"
bl_options = {"REGISTER"}
@classmethod
def poll(cls, context):
return context.object
def invoke(self, context, event):
# wm = context.window_manager
# return wm.invoke_props_dialog(self)
self.shift = event.shift
return self.execute(context)
def execute(self, context):
ob = context.object
#get name and check
if self.shift:
if ob.type != "GPENCIL":
self.report({'ERROR'}, 'Not a GP, no access to layers')
return {"CANCELLED"}
lay = ob.data.layers.active
if not lay:
self.report({'ERROR'}, 'No active layer found')
return {"CANCELLED"}
context.scene.gptoolprops.name_for_current_render = lay.info
else:
context.scene.gptoolprops.name_for_current_render = ob.name
# self.report({'INFO'}, 'Output Name changed')
return {"FINISHED"}
""" class GPTRD_OT_render_as_is(bpy.types.Operator):
bl_idname = "render.render_as_is"
bl_label = "render current"
bl_description = "Launch animation render with current setup"
bl_options = {"REGISTER"}
def execute(self, context):
err = initial_render_checks(context)
if err:
self.report({'ERROR'}, err)
return {"CANCELLED"}
return {"FINISHED"} """
### --- REGISTER
classes = (
GPTRD_OT_render_anim,
GPTRD_OT_setup_render_path,
GPTRD_OT_use_active_object_infos,
)
def register():
for cl in classes:
bpy.utils.register_class(cl)
def unregister():
for cl in classes:
bpy.utils.unregister_class(cl)
'''
## Potential cancelling method for image sequence rendering.
for cfra in range(start, end+1):
print("Baking frame " + str(cfra))
# update scene to new frame and bake to template image
scene.frame_set(cfra)
ret = bpy.ops.object.bake_image()
if 'CANCELLED' in ret:
return {'CANCELLED'}
'''
"""
class PBLAST_OT_render_wrap(bpy.types.Operator):
bl_idname = "render.render_wrap"
bl_label = "Render wraped"
bl_description = "render"
bl_options = {"REGISTER"}## need hide
use_view : bpy.props.BoolProperty(name='use_view', default=False)
def execute(self, context):
if self.use_view:## openGL
ret = bpy.ops.render.opengl('INVOKE_DEFAULT', animation=True, view_context=True)
else:## normal render
ret = bpy.ops.render.render('INVOKE_DEFAULT', animation=True)
return {"FINISHED"}
"""
""" if __name__ == "__main__":
register() """

View File

@ -36,7 +36,7 @@ class GPTB_PT_dataprop_panel(bpy.types.Panel):
## UI in Gpencil sidebar menu ## UI in Gpencil sidebar menu
class GPTB_PT_sidebar_panel(bpy.types.Panel): class GPTB_PT_sidebar_panel(bpy.types.Panel):
bl_label = "Toolbox" bl_label = "GP Toolbox"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Gpencil" bl_category = "Gpencil"
@ -50,18 +50,18 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
# addon_updater_ops.check_for_update_background() # addon_updater_ops.check_for_update_background()
# layout.label(text='View options:') # layout.label(text='View options:')
col = layout.column()
## flip X cam ## flip X cam
if context.scene.camera and context.scene.camera.scale.x < 0: if context.scene.camera and context.scene.camera.scale.x < 0:
# layout.label(text='! Flipped !') # layout.label(text='! Flipped !')
row = layout.row(align=True) row = col.row(align=True)
row.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT row.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT
row.label(text='',icon='LOOP_BACK') row.label(text='',icon='LOOP_BACK')
else: else:
layout.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT col.operator('gp.mirror_flipx', text = 'Mirror flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT
## draw/manipulation camera ## draw/manipulation camera
col = layout.column()
if context.scene.camera and context.scene.camera.name.startswith(('draw', 'obj')): if context.scene.camera and context.scene.camera.name.startswith(('draw', 'obj')):
row = col.row(align=True) row = col.row(align=True)
row.operator('gp.draw_cam_switch', text = 'Main cam', icon = 'OUTLINER_OB_CAMERA') row.operator('gp.draw_cam_switch', text = 'Main cam', icon = 'OUTLINER_OB_CAMERA')
@ -126,13 +126,11 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
layout.operator('gp.straight_stroke', icon ="CURVE_PATH") layout.operator('gp.straight_stroke', icon ="CURVE_PATH")
## Options ## Options
layout.separator() col = layout.column()
layout.label(text = 'Options:') col.label(text = 'Options:')
## Kf Jump filter ## Kf Jump filter
layout.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump col.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump
col = layout.column()
# col.prop(context.space_data.overlay, 'use_gpencil_onion_skin') # not often used # col.prop(context.space_data.overlay, 'use_gpencil_onion_skin') # not often used
if context.object and context.object.type == 'GPENCIL': if context.object and context.object.type == 'GPENCIL':
@ -157,41 +155,18 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
else: else:
col.label(text='No GP object selected') col.label(text='No GP object selected')
col.prop(context.scene.gptoolprops, 'edit_lines_opacity') col.prop(context.scene.gptoolprops, 'edit_lines_opacity')
row = col.row(align=True)
## realign / reproject
row.operator('gp.realign', icon='AXIS_FRONT')
## move in depth
row.operator('object.depth_proportional_move', text='Depth move', icon='TRANSFORM_ORIGINS')
## col.operator('gp.batch_reproject_all_frames') # text=Batch Reproject # added to context menu
## check drawing alignement
col.operator('gp.check_canvas_alignement', icon='DRIVER_ROTATIONAL_DIFFERENCE')
## Create empty frame on layer (ops stored under GP_colorize... might be best to separate in another panel )
col.operator('gp.create_empty_frames', icon='DECORATE_KEYFRAME')
## File checker
row = col.row(align=True)
row.operator('gp.file_checker', text = 'Check file', icon = 'SCENE_DATA')
row.operator('gp.links_checker', text = 'Check links', icon = 'UNLINKED')
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
# Mention update as notice # Mention update as notice
# addon_updater_ops.update_notice_box_ui(self, context) # addon_updater_ops.update_notice_box_ui(self, context)
# row = layout.row(align=False) # row = layout.row(align=False)
# row.label(text='arrow choice') # row.label(text='arrow choice')
# row.operator("my_operator.multi_op", text='', icon='TRIA_LEFT').left = 1 # row.operator("my_operator.multi_op", text='', icon='TRIA_LEFT').left = 1
# row.operator("my_operator.multi_op", text='', icon='TRIA_RIGHT').left = 0 # row.operator("my_operator.multi_op", text='', icon='TRIA_RIGHT').left = 0
class GPTB_PT_anim_manager(bpy.types.Panel): class GPTB_PT_anim_manager(bpy.types.Panel):
bl_label = "Animation manager" bl_label = "Animation Manager"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Gpencil" bl_category = "Gpencil"
@ -204,11 +179,12 @@ class GPTB_PT_anim_manager(bpy.types.Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
col = layout.column()
## Animation enable disable anim (shift click to select) OP_helpers.GPTB_OT_toggle_mute_animation ## Animation enable disable anim (shift click to select) OP_helpers.GPTB_OT_toggle_mute_animation
layout.operator('gp.list_disabled_anims') col.operator('gp.list_disabled_anims')
## Objs () ## Objs ()
row = layout.row(align=True) row = col.row(align=True)
row.label(text='Obj anims:') row.label(text='Obj anims:')
ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH'
ops.skip_gp = True ops.skip_gp = True
@ -220,7 +196,7 @@ class GPTB_PT_anim_manager(bpy.types.Panel):
ops.skip_obj = False ops.skip_obj = False
ops.mute = True ops.mute = True
## Gps ## Gps
row = layout.row(align=True) row = col.row(align=True)
row.label(text='Gp anims:') row.label(text='Gp anims:')
ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH'
ops.skip_gp = False ops.skip_gp = False
@ -232,6 +208,12 @@ class GPTB_PT_anim_manager(bpy.types.Panel):
ops.skip_obj = True ops.skip_obj = True
ops.mute = True ops.mute = True
## This can go in an extra category...
col = layout.column()
col.use_property_split = False
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
class GPTB_PT_toolbox_playblast(bpy.types.Panel): class GPTB_PT_toolbox_playblast(bpy.types.Panel):
bl_label = "Playblast" bl_label = "Playblast"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
@ -255,17 +237,13 @@ class GPTB_PT_toolbox_playblast(bpy.types.Panel):
row.operator('render.playblast_anim', text = 'Viewport').use_view = True row.operator('render.playblast_anim', text = 'Viewport').use_view = True
class GPTB_PT_tint_layers(bpy.types.Panel): class GPTB_PT_tint_layers(bpy.types.Panel):
bl_label = "Tint layers" bl_label = "Tint Layers"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Gpencil" bl_category = "Gpencil"
bl_parent_id = "GPTB_PT_sidebar_panel" bl_parent_id = "GPTB_PT_sidebar_panel"
bl_options = {'DEFAULT_CLOSED'} bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.scene.camera
# def draw_header(self,context): # def draw_header(self,context):
# self.layout.prop(context.scene.camera.data, "show_background_images", text="") # self.layout.prop(context.scene.camera.data, "show_background_images", text="")
@ -282,40 +260,65 @@ class GPTB_PT_tint_layers(bpy.types.Panel):
col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False
col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True
class GPTB_PT_render(bpy.types.Panel):
bl_label = "Render" class GPTB_PT_checker(bpy.types.Panel):
bl_label = "Checker"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Gpencil" bl_category = "Gpencil"
bl_parent_id = "GPTB_PT_sidebar_panel" bl_parent_id = "GPTB_PT_sidebar_panel"
bl_options = {'DEFAULT_CLOSED'} bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.scene.camera
# def draw_header(self,context): # def draw_header(self,context):
# self.layout.prop(context.scene.camera.data, "show_background_images", text="") # self.layout.prop(context.scene.camera.data, "show_background_images", text="")
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.operator('render.render_anim', text = 'Render invividually', icon = 'RENDERLAYERS').mode = 'INDIVIDUAL'#RENDER_STILL #RESTRICT_RENDER_OFF col = layout.column()
layout.operator('render.render_anim', text = 'Render grouped', icon = 'IMAGE_RGB').mode = 'GROUP' row = col.row(align=True)
## realign / reproject
row.operator('gp.realign', icon='AXIS_FRONT')
## move in depth
row.operator('object.depth_proportional_move', text='Depth move', icon='TRANSFORM_ORIGINS')
layout.separator() ## col.operator('gp.batch_reproject_all_frames') # text=Batch Reproject # added to context menu
row = layout.row() ## check drawing alignement
row.prop(context.scene.gptoolprops, 'name_for_current_render', text = 'Output name')#icon = 'OUTPUT' col.operator('gp.check_canvas_alignement', icon='DRIVER_ROTATIONAL_DIFFERENCE')
row.operator('render.use_active_object_name', text = '', icon='OUTLINER_DATA_GP_LAYER')#icon = 'OUTPUT'
layout.operator('render.setup_render_path', text = 'Setup output', icon = 'TOOL_SETTINGS')#SETTINGS ## File checker
row = col.row(align=True)
blend = bpy.data.filepath row.operator('gp.file_checker', text = 'Check file', icon = 'SCENE_DATA')
if blend: row.operator('gp.links_checker', text = 'Check links', icon = 'UNLINKED')
blend = Path(blend)
out = blend.parents[1] / "compo" / "base"
layout.operator("wm.path_open", text='Open render folder', icon='FILE_FOLDER').filepath = str(out)
class GPTB_PT_color(bpy.types.Panel):
bl_label = "Color"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Gpencil"
bl_parent_id = "GPTB_PT_sidebar_panel"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
## Create empty frame on layer
layout.operator('gp.create_empty_frames', icon='DECORATE_KEYFRAME')
""" # unused : added in Animation Manager
class GPTB_PT_extra(bpy.types.Panel):
bl_label = "Extra"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Gpencil"
bl_parent_id = "GPTB_PT_sidebar_panel"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
col = layout.column()
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
"""
""" """
## unused -- (integrated in sidebar_panel) ## unused -- (integrated in sidebar_panel)
@ -363,11 +366,12 @@ def palette_manager_menu(self, context):
classes = ( classes = (
GPTB_PT_sidebar_panel, GPTB_PT_sidebar_panel,
GPTB_PT_checker,
GPTB_PT_anim_manager, GPTB_PT_anim_manager,
GPTB_PT_toolbox_playblast, GPTB_PT_color,
GPTB_PT_tint_layers, GPTB_PT_tint_layers,
GPTB_PT_render, GPTB_PT_toolbox_playblast,
## GPTB_PT_cam_ref_panel, # GPTB_PT_extra,
) )
def register(): def register():

View File

@ -15,7 +15,7 @@ bl_info = {
"name": "GP toolbox", "name": "GP toolbox",
"description": "Set of tools for Grease Pencil in animation production", "description": "Set of tools for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux", "author": "Samuel Bernou, Christophe Seux",
"version": (1, 6, 9), "version": (1, 7, 0),
"blender": (2, 91, 0), "blender": (2, 91, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "", "warning": "",
@ -43,7 +43,6 @@ from . import OP_cursor_snap_canvas
from . import OP_palettes from . import OP_palettes
from . import OP_brushes from . import OP_brushes
from . import OP_file_checker from . import OP_file_checker
from . import OP_render
from . import OP_copy_paste from . import OP_copy_paste
from . import OP_realign from . import OP_realign
from . import OP_depth_move from . import OP_depth_move
@ -571,7 +570,6 @@ def register():
OP_palettes.register() OP_palettes.register()
OP_brushes.register() OP_brushes.register()
OP_cursor_snap_canvas.register() OP_cursor_snap_canvas.register()
OP_render.register()
OP_copy_paste.register() OP_copy_paste.register()
OP_realign.register() OP_realign.register()
OP_depth_move.register() OP_depth_move.register()
@ -612,7 +610,6 @@ def unregister():
OP_depth_move.unregister() OP_depth_move.unregister()
OP_realign.unregister() OP_realign.unregister()
OP_copy_paste.unregister() OP_copy_paste.unregister()
OP_render.unregister()
OP_cursor_snap_canvas.unregister() OP_cursor_snap_canvas.unregister()
OP_brushes.unregister() OP_brushes.unregister()
OP_palettes.unregister() OP_palettes.unregister()

View File

@ -157,7 +157,7 @@ class GP_PG_ToolsSettings(bpy.types.PropertyGroup):
default=False, update=cursor_follow_update) default=False, update=cursor_follow_update)
edit_lines_opacity : FloatProperty( edit_lines_opacity : FloatProperty(
name="edit lines Opacity", description="Change edit lines opacity for all grease pencils", name="Edit Lines Opacity", description="Change edit lines opacity for all grease pencils",
default=0.5, min=0.0, max=1.0, step=3, precision=2, update=change_edit_lines_opacity) default=0.5, min=0.0, max=1.0, step=3, precision=2, update=change_edit_lines_opacity)
## render ## render