diff --git a/CHANGELOG.md b/CHANGELOG.md index b80e818..b637f08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # 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 - 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 -1.3.2: +1.3.2 - change: disable manip cam name drawing - 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. - 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 -1.2.2: +1.2.2 - fix: realign anim return error -1.2.1: +1.2.1 - fix: Breakdowner initial error check -1.2.0: +1.2.0 - feat: New depth move operator that handle both perspective and orthographic cam - 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: 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 - 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 -1.0.9: +1.0.9 - 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 -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) -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) -1.0.4: +1.0.4 - UI: Better cam ref exposition in Toolbox panel - Access to opacity - merge activation bool with source type icon - 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. -1.0.2: +1.0.2 - pref: Added option to disable always remap relative on save in addon-preference -1.0.1: +1.0.1 - fix: copy paste problems - 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+) -1.0.0: +1.0.0 - Compatible with official grease pencil tools - removed box deform and rotate canvas that existed in other -0.9.3: +0.9.3 - feat: keyframe jump keys are now auto-binded - UI: added keyframe jump customisation in addon pref - 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 - code: added tracker url - updater: remove updater temp file, reset minimum version, turn off verbose mode -0.9.1: +0.9.1 - Public release - prefs: added fps as part of project settings @@ -240,38 +251,38 @@ - doc: Added fully-detailed french readme -0.8.0: +0.8.0 - feat: Added background_rendering playblast, derivating from Tonton's playblaster - stripped associated properties from properties.py and passed as wm props. -0.7.2: +0.7.2 - fix: Palette importer bug -0.7.0: +0.7.0 - 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) -0.6.2: +0.6.2 - 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` - 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 -0.6.0: +0.6.0 - feat: Include GP clipoard's "In place" custom cut/copy/paste using OS clipboard -0.5.9: +0.5.9 - feat: render exporter - 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 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 -0.5.7: +0.5.7 - 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. - 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) -0.5.4: +0.5.4 - feat: anim manager in his own GP_toolbox submenu: - button to list disabled anim (allow to quickly check state of the scene) @@ -303,19 +314,19 @@ - shift clic to target selection only - 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) - 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) - Changed method for canvas rotation to more robust rotate axis. - Add operators on link checker to open containing folder/file of link - Refactor: file checkers in their own file -0.5.1: +0.5.1 - fix: error when empty material slot on GP object. - fix: cursor snap on GP canvas when GP is parented @@ -330,11 +341,11 @@ - set show slider and sync range - set fps to 24 -0.4.6: +0.4.6 - feat: basic Palette manager with base material check and warning -0.4.5: +0.4.5 - open blender config folder from addon preference - 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) -0.4.4: +0.4.4 - 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 -0.4.2: +0.4.2 - feat: GP canvas cursor snap wiht new `view3d.cusor_snap` operator - fix: canvas rotate works with parented camera ! - 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) -0.4.0: +0.4.0 - 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 autolock in interface @@ -373,47 +384,47 @@ - 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 -0.3.7: +0.3.7 - UI: new interface with tabs for addon preferences - UI: possible to disable color panel from preference (might be deleted if unusable) - docs: change readme changelog format and correct doc -0.3.6: +0.3.6 - 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: 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 -0.3.3: +0.3.3 - version 1 beta of gmic colorize - 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 - 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 shortcut to rotate canvas - fix duplicate class -0.2.2: +0.2.2 - separated props resolution_percentage parameter - playblast options for launching folder and opening folder -0.2.1: +0.2.1 - playblast feature - Button to go zoom 100% or fit screen @@ -421,22 +432,22 @@ - 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) -0.2.0: +0.2.0 - UI: Toggle camera background images from Toolbox panel - UI: quick access to passepartout - Feature: option to use namespace for pseudo color -0.1.5: +0.1.5 - added CGC-auto-updater -0.1.3: +0.1.3 - flip cam x - inital stage of overlay toggle (need pref/multiple pref) -0.1.2: +0.1.2 - subpanel of GP data (instead of direct append) - initial commit with GP pseudo color \ No newline at end of file diff --git a/GP_guided_colorize/GP_colorize.py b/GP_guided_colorize/GP_colorize.py index da29198..e34a28e 100644 --- a/GP_guided_colorize/GP_colorize.py +++ b/GP_guided_colorize/GP_colorize.py @@ -13,7 +13,7 @@ import bpy -from . import OP_line_closer +# from . import OP_line_closer from . import OP_create_empty_frames @@ -45,11 +45,11 @@ def register(): for cls in classes: bpy.utils.register_class(cls) 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) def unregister(): - OP_line_closer.unregister() + # OP_line_closer.unregister() OP_create_empty_frames.unregister() for cls in reversed(classes): bpy.utils.unregister_class(cls) diff --git a/OP_copy_paste.py b/OP_copy_paste.py index 719cc95..654c3ab 100644 --- a/OP_copy_paste.py +++ b/OP_copy_paste.py @@ -637,13 +637,16 @@ class GPCLIP_PT_clipboard_ui(bpy.types.Panel): def draw(self, context): 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.cut_strokes', text='Cut strokes', icon='PASTEFLIPUP') - layout.operator('gp.paste_strokes', text='Paste strokes', icon='PASTEDOWN') - layout.separator() - layout.operator('gp.copy_multi_strokes', text='Copy layers', icon='COPYDOWN') - layout.operator('gp.paste_multi_strokes', text='Paste layers', icon='PASTEDOWN') + col.operator('gp.paste_strokes', text='Paste strokes', icon='PASTEDOWN') + # layout.separator() + col = layout.column(align=True) + col.operator('gp.copy_multi_strokes', text='Copy layers', icon='COPYDOWN') + col.operator('gp.paste_multi_strokes', text='Paste layers', icon='PASTEDOWN') ###---TEST zone diff --git a/OP_render.py b/OP_render.py deleted file mode 100644 index 71aed48..0000000 --- a/OP_render.py +++ /dev/null @@ -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() """ \ No newline at end of file diff --git a/UI_tools.py b/UI_tools.py index 8de0c41..b03b348 100644 --- a/UI_tools.py +++ b/UI_tools.py @@ -36,7 +36,7 @@ class GPTB_PT_dataprop_panel(bpy.types.Panel): ## UI in Gpencil sidebar menu class GPTB_PT_sidebar_panel(bpy.types.Panel): - bl_label = "Toolbox" + bl_label = "GP Toolbox" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" @@ -50,18 +50,18 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel): # addon_updater_ops.check_for_update_background() # layout.label(text='View options:') + col = layout.column() ## flip X cam if context.scene.camera and context.scene.camera.scale.x < 0: # 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.label(text='',icon='LOOP_BACK') 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 - col = layout.column() if context.scene.camera and context.scene.camera.name.startswith(('draw', 'obj')): row = col.row(align=True) 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") ## Options - layout.separator() - layout.label(text = 'Options:') + col = layout.column() + col.label(text = 'Options:') ## Kf Jump filter - layout.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump - - col = layout.column() + col.prop(context.scene.gptoolprops, 'keyframe_type', text='Jump On') # Keyframe Jump # col.prop(context.space_data.overlay, 'use_gpencil_onion_skin') # not often used if context.object and context.object.type == 'GPENCIL': @@ -157,41 +155,18 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel): else: col.label(text='No GP object selected') - 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 # addon_updater_ops.update_notice_box_ui(self, context) - # row = layout.row(align=False) # 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_RIGHT').left = 0 class GPTB_PT_anim_manager(bpy.types.Panel): - bl_label = "Animation manager" + bl_label = "Animation Manager" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" @@ -204,11 +179,12 @@ class GPTB_PT_anim_manager(bpy.types.Panel): def draw(self, context): layout = self.layout layout.use_property_split = True + col = layout.column() ## 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 () - row = layout.row(align=True) + row = col.row(align=True) row.label(text='Obj anims:') ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops.skip_gp = True @@ -220,7 +196,7 @@ class GPTB_PT_anim_manager(bpy.types.Panel): ops.skip_obj = False ops.mute = True ## Gps - row = layout.row(align=True) + row = col.row(align=True) row.label(text='Gp anims:') ops = row.operator('gp.toggle_mute_animation', text = 'ON')#, icon = 'GRAPH' ops.skip_gp = False @@ -232,6 +208,12 @@ class GPTB_PT_anim_manager(bpy.types.Panel): ops.skip_obj = 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): bl_label = "Playblast" 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 class GPTB_PT_tint_layers(bpy.types.Panel): - bl_label = "Tint layers" + bl_label = "Tint Layers" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - return context.scene.camera - # def draw_header(self,context): # 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", 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_region_type = "UI" bl_category = "Gpencil" bl_parent_id = "GPTB_PT_sidebar_panel" bl_options = {'DEFAULT_CLOSED'} - @classmethod - def poll(cls, context): - return context.scene.camera - # def draw_header(self,context): # self.layout.prop(context.scene.camera.data, "show_background_images", text="") def draw(self, context): layout = self.layout - layout.operator('render.render_anim', text = 'Render invividually', icon = 'RENDERLAYERS').mode = 'INDIVIDUAL'#RENDER_STILL #RESTRICT_RENDER_OFF - layout.operator('render.render_anim', text = 'Render grouped', icon = 'IMAGE_RGB').mode = 'GROUP' + col = layout.column() + 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() - row = layout.row() - row.prop(context.scene.gptoolprops, 'name_for_current_render', text = 'Output name')#icon = 'OUTPUT' - row.operator('render.use_active_object_name', text = '', icon='OUTLINER_DATA_GP_LAYER')#icon = 'OUTPUT' + ## 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') - layout.operator('render.setup_render_path', text = 'Setup output', icon = 'TOOL_SETTINGS')#SETTINGS - - blend = bpy.data.filepath - if blend: - blend = Path(blend) - out = blend.parents[1] / "compo" / "base" - layout.operator("wm.path_open", text='Open render folder', icon='FILE_FOLDER').filepath = str(out) + ## 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') +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) @@ -363,11 +366,12 @@ def palette_manager_menu(self, context): classes = ( GPTB_PT_sidebar_panel, +GPTB_PT_checker, GPTB_PT_anim_manager, -GPTB_PT_toolbox_playblast, +GPTB_PT_color, GPTB_PT_tint_layers, -GPTB_PT_render, -## GPTB_PT_cam_ref_panel, +GPTB_PT_toolbox_playblast, +# GPTB_PT_extra, ) def register(): diff --git a/__init__.py b/__init__.py index 4de2f91..b83125b 100755 --- a/__init__.py +++ b/__init__.py @@ -15,7 +15,7 @@ bl_info = { "name": "GP toolbox", "description": "Set of tools for Grease Pencil in animation production", "author": "Samuel Bernou, Christophe Seux", -"version": (1, 6, 9), +"version": (1, 7, 0), "blender": (2, 91, 0), "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "warning": "", @@ -43,7 +43,6 @@ from . import OP_cursor_snap_canvas from . import OP_palettes from . import OP_brushes from . import OP_file_checker -from . import OP_render from . import OP_copy_paste from . import OP_realign from . import OP_depth_move @@ -571,7 +570,6 @@ def register(): OP_palettes.register() OP_brushes.register() OP_cursor_snap_canvas.register() - OP_render.register() OP_copy_paste.register() OP_realign.register() OP_depth_move.register() @@ -612,7 +610,6 @@ def unregister(): OP_depth_move.unregister() OP_realign.unregister() OP_copy_paste.unregister() - OP_render.unregister() OP_cursor_snap_canvas.unregister() OP_brushes.unregister() OP_palettes.unregister() diff --git a/properties.py b/properties.py index dd69e49..d254ef1 100755 --- a/properties.py +++ b/properties.py @@ -157,7 +157,7 @@ class GP_PG_ToolsSettings(bpy.types.PropertyGroup): default=False, update=cursor_follow_update) 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) ## render