Fix multiscene ops and batch script generation
0.6.0: - feat: button to generate a background rendering script to batch multi-scene - fix: exposed checkbox to change scene AA settings, should be on except if there are NG_merges. (auto-off when using merge nodes buttons) - fix: default generated scene have native AA - fix: adding layers from object in other scene use active scene (stop always rerouting to 'Render' scene)
This commit is contained in:
		
							parent
							
								
									d3871dcc88
								
							
						
					
					
						commit
						7b79542c6a
					
				| @ -14,6 +14,13 @@ Activate / deactivate layer opaticty according to prefix | |||||||
| Activate / deactivate all masks using MA layers | Activate / deactivate all masks using MA layers | ||||||
| --> | --> | ||||||
| 
 | 
 | ||||||
|  | 0.6.0: | ||||||
|  | 
 | ||||||
|  | - feat: button to generate a background rendering script to batch multi-scene | ||||||
|  | - fix: exposed checkbox to change scene AA settings, should be on except if there are NG_merges. (auto-off when using merge nodes buttons) | ||||||
|  | - fix: default generated scene have native AA | ||||||
|  | - fix: adding layers from object in other scene use active scene (stop always rerouting to 'Render' scene) | ||||||
|  | 
 | ||||||
| 0.5.9 | 0.5.9 | ||||||
| 
 | 
 | ||||||
| - feat: Select which scene to render | - feat: Select which scene to render | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ class GPEXP_OT_add_layer_to_render(bpy.types.Operator): | |||||||
|         return {"FINISHED"} |         return {"FINISHED"} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def export_gp_objects(oblist, exclude_list=[]): | def export_gp_objects(oblist, exclude_list=[], scene=None): | ||||||
|     # Skip layer containing element in excluyde list |     # Skip layer containing element in excluyde list | ||||||
|     if not isinstance(oblist, list): |     if not isinstance(oblist, list): | ||||||
|         oblist = [oblist] |         oblist = [oblist] | ||||||
| @ -54,10 +54,10 @@ def export_gp_objects(oblist, exclude_list=[]): | |||||||
|             # if l.hide:  |             # if l.hide:  | ||||||
|             #     continue |             #     continue | ||||||
|             if l.hide or any(x + '_' in l.info for x in exclude_list): # exclude hided ? |             if l.hide or any(x + '_' in l.info for x in exclude_list): # exclude hided ? | ||||||
|                 l.viewlayer_render = fn.get_view_layer('exclude').name # assign "exclude" |                 l.viewlayer_render = fn.get_view_layer('exclude', scene=scene).name # assign "exclude" | ||||||
|                 continue |                 continue | ||||||
| 
 | 
 | ||||||
|             _vl, _cp = gen_vlayer.get_set_viewlayer_from_gp(ob, l) # scene=fn.get_render_scene()) |             _vl, _cp = gen_vlayer.get_set_viewlayer_from_gp(ob, l, scene=scene) # scene=fn.get_render_scene()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ## send operator with mode ALL or SELECTED to batch build | ## send operator with mode ALL or SELECTED to batch build | ||||||
| @ -75,17 +75,22 @@ class GPEXP_OT_add_objects_to_render(bpy.types.Operator): | |||||||
| 
 | 
 | ||||||
|     def execute(self, context): |     def execute(self, context): | ||||||
|         # create render scene |         # create render scene | ||||||
|         fn.get_render_scene() |         if context.scene.name == 'Scene': | ||||||
|  |             scn = fn.get_render_scene() | ||||||
|  |         else: | ||||||
|  |             scn = context.scene | ||||||
|  | 
 | ||||||
|  |          | ||||||
|         excludes = [] # ['MA', 'IN'] # Get list dynamically |         excludes = [] # ['MA', 'IN'] # Get list dynamically | ||||||
|         if self.mode == 'SELECTED': |         if self.mode == 'SELECTED': | ||||||
|             export_gp_objects([o for o in context.selected_objects if o.type == 'GPENCIL'], exclude_list=excludes) # excludes |             export_gp_objects([o for o in context.selected_objects if o.type == 'GPENCIL'], exclude_list=excludes, scene=scn) | ||||||
| 
 | 
 | ||||||
|         elif self.mode == 'ALL': |         elif self.mode == 'ALL': | ||||||
|             scn = bpy.data.scenes.get('Scene') |             # scn = bpy.data.scenes.get('Scene') | ||||||
|             if not scn: |             # if not scn: | ||||||
|                 self.report({'ERROR'}, 'Could not found default scene') |             #     self.report({'ERROR'}, 'Could not found default scene') | ||||||
|                 return {"CANCELLED"} |             #     return {"CANCELLED"} | ||||||
|             export_gp_objects([o for o in scn.objects if o.type == 'GPENCIL' and not o.hide_get()], exclude_list=excludes) # excludes |             export_gp_objects([o for o in scn.objects if o.type == 'GPENCIL' and not o.hide_get()], exclude_list=excludes, scene=scn) | ||||||
| 
 | 
 | ||||||
|         return {"FINISHED"} |         return {"FINISHED"} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -211,12 +211,48 @@ class GPEXP_OT_activate_only_selected_layers(bpy.types.Operator): | |||||||
|         return {"FINISHED"} |         return {"FINISHED"} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ### TODO reset scene settings (set settings ) | ||||||
|  | 
 | ||||||
|  | class GPEXP_OT_reset_render_settings(bpy.types.Operator): | ||||||
|  |     bl_idname = "gp.reset_render_settings" | ||||||
|  |     bl_label = "Reset Render Settings" | ||||||
|  |     bl_description = "Reset render settings on all scene, disabling AA nodes when there is no Merge nodegroup" | ||||||
|  |     bl_options = {"REGISTER"} | ||||||
|  | 
 | ||||||
|  |     def execute(self, context): | ||||||
|  |         for scn in bpy.data.scenes: | ||||||
|  |             if scn.name == 'Scene': | ||||||
|  |                 # don't touch original scene | ||||||
|  |                 continue | ||||||
|  |              | ||||||
|  |             # set a unique preview output | ||||||
|  |             # - avoid possible write/sync overlap (point to tmp on linux ?) | ||||||
|  |             # - allow to monitor output of a scene and possibly use Overwrite | ||||||
|  |              | ||||||
|  |             if scn.render.filepath.startswith('//render/preview/'): | ||||||
|  |                 scn.render.filepath = f'//render/preview/{bpy.path.clean_nam(scn.name)}/preview_' | ||||||
|  |              | ||||||
|  |             if not scn.use_nodes: | ||||||
|  |                 continue | ||||||
|  |              | ||||||
|  |             # set the settings depending on merges node presences | ||||||
|  |             use_native_aa = True | ||||||
|  |             for n in scn.node_tree.nodes: | ||||||
|  |                 if n.name.startswith('merge_NG_'): | ||||||
|  |                     use_native_aa = False | ||||||
|  |                     break | ||||||
|  | 
 | ||||||
|  |             fn.scene_aa(scene=scn, toggle=use_native_aa) | ||||||
|  | 
 | ||||||
|  |         return {"FINISHED"} | ||||||
|  | 
 | ||||||
| classes=( | classes=( | ||||||
| GPEXP_OT_mute_toggle_output_nodes, | GPEXP_OT_mute_toggle_output_nodes, | ||||||
| GPEXP_OT_set_output_node_format, | GPEXP_OT_set_output_node_format, | ||||||
| GPEXP_OT_number_outputs, | GPEXP_OT_number_outputs, | ||||||
| GPEXP_OT_enable_all_viewlayers, | GPEXP_OT_enable_all_viewlayers, | ||||||
| GPEXP_OT_activate_only_selected_layers, | GPEXP_OT_activate_only_selected_layers, | ||||||
|  | GPEXP_OT_reset_render_settings, | ||||||
| # GPEXP_OT_normalize_outnames, | # GPEXP_OT_normalize_outnames, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -110,6 +110,8 @@ def merge_layers(rlayers, obname=None, active=None, disconnect=True, color=None) | |||||||
|     #     fn.clean_nodegroup_inputs(dg) |     #     fn.clean_nodegroup_inputs(dg) | ||||||
|     #     # fn.clear_nodegroup_content_if_disconnected(dg.node_tree) |     #     # fn.clear_nodegroup_content_if_disconnected(dg.node_tree) | ||||||
| 
 | 
 | ||||||
|  |     bpy.context.scene.use_aa = False # trigger fn.scene_aa(toggle=False) | ||||||
|  | 
 | ||||||
|     return ng, out |     return ng, out | ||||||
| 
 | 
 | ||||||
| class GPEXP_OT_merge_viewlayers_to_active(bpy.types.Operator): | class GPEXP_OT_merge_viewlayers_to_active(bpy.types.Operator): | ||||||
| @ -265,7 +267,11 @@ class GPEXP_OT_merge_selected_viewlayer_nodes(bpy.types.Operator): | |||||||
|     disconnect : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'}) |     disconnect : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'}) | ||||||
| 
 | 
 | ||||||
|     def execute(self, context): |     def execute(self, context): | ||||||
|  |         if context.scene.name == 'Scene': | ||||||
|             render = bpy.data.scenes.get('Render') |             render = bpy.data.scenes.get('Render') | ||||||
|  |         else: | ||||||
|  |             render = context.scene | ||||||
|  | 
 | ||||||
|         if not render: |         if not render: | ||||||
|             self.report({'ERROR'}, 'No render scene') |             self.report({'ERROR'}, 'No render scene') | ||||||
|             return {"CANCELLED"} |             return {"CANCELLED"} | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| import bpy | import bpy | ||||||
| from . import fn | from . import fn | ||||||
| from time import time | from time import time, strftime | ||||||
|  | from pathlib import Path | ||||||
|  | import sys | ||||||
| 
 | 
 | ||||||
| from bpy.types import Panel, UIList, Operator, PropertyGroup, Menu | from bpy.types import Panel, UIList, Operator, PropertyGroup, Menu | ||||||
| from bpy.props import PointerProperty, IntProperty, BoolProperty, StringProperty, EnumProperty, FloatProperty | from bpy.props import PointerProperty, IntProperty, BoolProperty, StringProperty, EnumProperty, FloatProperty | ||||||
| @ -101,10 +103,98 @@ class GPEXP_OT_render_selected_scene(bpy.types.Operator): | |||||||
|         return {"FINISHED"} |         return {"FINISHED"} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class GPEXP_OT_bg_render_script_selected_scene(bpy.types.Operator): | ||||||
|  |     bl_idname = "gp.bg_render_script_selected_scenes" | ||||||
|  |     bl_label = "Create Selected Scene Render Batch " | ||||||
|  |     bl_description = "Create a batch script to render all selected scenes in a selection popup" | ||||||
|  |     bl_options = {"REGISTER"} | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def poll(cls, context): | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     def invoke(self, context, event): | ||||||
|  |         context.scene.scenes_list.clear() | ||||||
|  |         for s in bpy.data.scenes: | ||||||
|  |             scn_item = context.scene.scenes_list.add() | ||||||
|  |             scn_item.name = s.name | ||||||
|  |             scn_item.select = s.name != 'Scene' | ||||||
|  | 
 | ||||||
|  |         return context.window_manager.invoke_props_dialog(self, width=500) | ||||||
|  | 
 | ||||||
|  |     def draw(self, context): | ||||||
|  |         layout = self.layout | ||||||
|  |         col = layout.column() | ||||||
|  |         for si in context.scene.scenes_list: | ||||||
|  |             row = col.row() | ||||||
|  |             row.prop(si, 'select',text='') | ||||||
|  |             row.label(text=si.name) | ||||||
|  | 
 | ||||||
|  |             ## Display warnings | ||||||
|  |             scn = bpy.data.scenes.get(si.name) | ||||||
|  |             # compare to existing Rlayers (overkill ?) | ||||||
|  |             # vls = [scn.view_layers.get(n.layer) for n in rlayers_nodes if scn.view_layers.get(n.layer)] | ||||||
|  |              | ||||||
|  |             vls = [vl for vl in scn.view_layers if vl.name != 'View Layer'] | ||||||
|  |      | ||||||
|  |             if vls: | ||||||
|  |                 exclude_count = len([vl for vl in vls if not vl.use]) | ||||||
|  |                 if exclude_count: | ||||||
|  |                     row.label(text=f'{exclude_count}/{len(vls)} excluded viewlayers', icon='ERROR')              | ||||||
|  | 
 | ||||||
|  |             if not scn.use_nodes: | ||||||
|  |                 row.label(text='use_node deactivated', icon='ERROR') | ||||||
|  |                 continue | ||||||
|  | 
 | ||||||
|  |             outfiles = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE'] | ||||||
|  |             if not outfiles: | ||||||
|  |                 row.label(text='No output files nodes', icon='ERROR') | ||||||
|  |                 continue | ||||||
|  |              | ||||||
|  |             outnum = len(outfiles) | ||||||
|  |             muted = len([x for x in outfiles if x.mute]) | ||||||
|  |             if muted == outnum: | ||||||
|  |                 row.label(text='All output file are muted', icon='ERROR') | ||||||
|  |                 continue | ||||||
|  |              | ||||||
|  |             elif muted: | ||||||
|  |                 row.label(text=f'{muted}/{outnum} output file muted', icon='ERROR') | ||||||
|  |                 continue | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     def execute(self, context): | ||||||
|  |         platform = sys.platform | ||||||
|  |          | ||||||
|  |         blend = Path(bpy.data.filepath) | ||||||
|  | 
 | ||||||
|  |         scn_to_render = [si.name for si in context.scene.scenes_list if si.select] | ||||||
|  |         batch_file = blend.parent / f'{blend.stem}--{len(scn_to_render)}batch_{strftime("%m-%d-%H")}.sh' | ||||||
|  | 
 | ||||||
|  |         if platform.startswith('win'): | ||||||
|  |             script_text = ['@ECHO OFF'] | ||||||
|  |             batch_file =  batch_file.with_suffix('.bat') | ||||||
|  |         else: | ||||||
|  |             script_text = ['#!/bin/bash'] | ||||||
|  | 
 | ||||||
|  |         print('batch_file: ', batch_file) | ||||||
|  |         for scn_name in scn_to_render: | ||||||
|  |             cmd = f'"{bpy.app.binary_path}" -b "{bpy.data.filepath}" -S "{scn_name}" -a' | ||||||
|  |             script_text.append(cmd) | ||||||
|  |          | ||||||
|  |         script_text.append('echo --- END BATCH ---') | ||||||
|  |         script_text.append('pause') | ||||||
|  |          | ||||||
|  |         with batch_file.open('w') as fd: | ||||||
|  |             fd.write('\n'.join(script_text)) | ||||||
|  | 
 | ||||||
|  |         self.report({'INFO'}, f'Batch script generated: {batch_file}') | ||||||
|  |         return {"FINISHED"} | ||||||
|  | 
 | ||||||
| classes=( | classes=( | ||||||
| GPEXP_scene_select_prop, | GPEXP_scene_select_prop, | ||||||
| GPEXP_OT_render_selected_scene, | GPEXP_OT_render_selected_scene, | ||||||
| GPEXP_OT_render_all_scenes, | GPEXP_OT_render_all_scenes, | ||||||
|  | GPEXP_OT_bg_render_script_selected_scene, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| def register():  | def register():  | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								__init__.py
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								__init__.py
									
									
									
									
									
								
							| @ -2,7 +2,7 @@ bl_info = { | |||||||
|     "name": "GP Render", |     "name": "GP Render", | ||||||
|     "description": "Organise export of gp layers through compositor output", |     "description": "Organise export of gp layers through compositor output", | ||||||
|     "author": "Samuel Bernou", |     "author": "Samuel Bernou", | ||||||
|     "version": (0, 5, 9), |     "version": (0, 6, 0), | ||||||
|     "blender": (2, 93, 0), |     "blender": (2, 93, 0), | ||||||
|     "location": "View3D", |     "location": "View3D", | ||||||
|     "warning": "", |     "warning": "", | ||||||
| @ -25,6 +25,11 @@ from . import prefs | |||||||
| from . import OP_setup_layers | from . import OP_setup_layers | ||||||
| from . import ui | from . import ui | ||||||
| 
 | 
 | ||||||
|  | from .fn import scene_aa | ||||||
|  | 
 | ||||||
|  | def update_scene_aa(context, scene): | ||||||
|  |     scene_aa(toggle=bpy.context.scene.use_aa) | ||||||
|  | 
 | ||||||
| import bpy | import bpy | ||||||
| 
 | 
 | ||||||
| def register(): | def register(): | ||||||
| @ -46,6 +51,14 @@ def register(): | |||||||
|     OP_setup_layers.register() |     OP_setup_layers.register() | ||||||
|     ui.register() |     ui.register() | ||||||
|     # bpy.types.Scene.pgroup_name = bpy.props.PointerProperty(type = PROJ_PGT_settings) |     # bpy.types.Scene.pgroup_name = bpy.props.PointerProperty(type = PROJ_PGT_settings) | ||||||
|  |     bpy.types.Scene.use_aa = bpy.props.BoolProperty( | ||||||
|  |         name='Use Native Anti Aliasing',  | ||||||
|  |         default=True,  | ||||||
|  |         description='\ | ||||||
|  | Should be Off only if tree contains a merge_NG or alpha-over-combined renderlayers.\n\ | ||||||
|  | Auto-set to Off when using node merge button\n\ | ||||||
|  | Toggle: AA settings of and muting AA nested-nodegroup',  | ||||||
|  |         update=update_scene_aa) | ||||||
| 
 | 
 | ||||||
| def unregister(): | def unregister(): | ||||||
|     if bpy.app.background: |     if bpy.app.background: | ||||||
| @ -66,7 +79,7 @@ def unregister(): | |||||||
|     OP_add_layer.unregister() |     OP_add_layer.unregister() | ||||||
|     prefs.unregister() |     prefs.unregister() | ||||||
| 
 | 
 | ||||||
|     # del bpy.types.Scene.pgroup_name |     del bpy.types.Scene.use_aa | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     register() |     register() | ||||||
							
								
								
									
										96
									
								
								fn.py
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								fn.py
									
									
									
									
									
								
							| @ -107,12 +107,26 @@ def set_file_output_format(fo): | |||||||
|     # fo.format.color_depth = '8' |     # fo.format.color_depth = '8' | ||||||
|     # fo.format.compression = 15 |     # fo.format.compression = 15 | ||||||
| 
 | 
 | ||||||
| def set_settings(scene=None): | 
 | ||||||
|  | def set_scene_aa_settings(scene=None, aa=True): | ||||||
|  |     '''aa == using native AA, else disable scene AA''' | ||||||
|     if not scene: |     if not scene: | ||||||
|         scene = bpy.context.scene |         scene = bpy.context.scene | ||||||
|     # specify scene settings for these kind of render |     if aa: | ||||||
|  |         scene.eevee.taa_render_samples = 32 | ||||||
|  |         scene.grease_pencil_settings.antialias_threshold = 1 | ||||||
|  |     else: | ||||||
|         scene.eevee.taa_render_samples = 1 |         scene.eevee.taa_render_samples = 1 | ||||||
|         scene.grease_pencil_settings.antialias_threshold = 0 |         scene.grease_pencil_settings.antialias_threshold = 0 | ||||||
|  | 
 | ||||||
|  | def set_settings(scene=None, aa=True): | ||||||
|  |     '''aa == using native AA, else disable scene AA''' | ||||||
|  |     if not scene: | ||||||
|  |         scene = bpy.context.scene | ||||||
|  |      | ||||||
|  |     # specify scene settings for these kind of render | ||||||
|  |     set_scene_aa_settings(scene=scene, aa=aa) | ||||||
|  | 
 | ||||||
|     scene.render.film_transparent = True |     scene.render.film_transparent = True | ||||||
|     scene.render.use_compositing = True |     scene.render.use_compositing = True | ||||||
|     scene.render.use_sequencer = False |     scene.render.use_sequencer = False | ||||||
| @ -121,11 +135,25 @@ def set_settings(scene=None): | |||||||
|     scene.render.resolution_percentage = 100 |     scene.render.resolution_percentage = 100 | ||||||
| 
 | 
 | ||||||
|     # output (fast write settings since this is just to delete afterwards...) |     # output (fast write settings since this is just to delete afterwards...) | ||||||
|     scene.render.filepath = '//render/preview/preview_' |     scene.render.filepath = f'//render/preview/{scene.name}/preview_' | ||||||
|     scene.render.image_settings.file_format = 'JPEG' |     scene.render.image_settings.file_format = 'JPEG' | ||||||
|     scene.render.image_settings.color_mode = 'RGB' |     scene.render.image_settings.color_mode = 'RGB' | ||||||
|     scene.render.image_settings.quality = 0 |     scene.render.image_settings.quality = 0 | ||||||
| 
 | 
 | ||||||
|  | def scene_aa(scene=None, toggle=True): | ||||||
|  |     '''Change scene AA settings and commute AA nodes according to toggle''' | ||||||
|  |     if not scene: | ||||||
|  |         scene=bpy.context.scene | ||||||
|  | 
 | ||||||
|  |     # enable/disable native anti-alias on active scene | ||||||
|  |     set_scene_aa_settings(scene=scene, aa=toggle)     | ||||||
|  |     # mute/unmute AA nodegroups | ||||||
|  |     for n in scene.node_tree.nodes: | ||||||
|  |         if n.type == 'GROUP' and n.name.startswith('NG_'): | ||||||
|  |             # n.mute = False # mute whole nodegroup ? | ||||||
|  |             for gn in n.node_tree.nodes: | ||||||
|  |                 if gn.type == 'GROUP' and gn.node_tree.name == 'AA': | ||||||
|  |                     gn.mute = toggle | ||||||
| 
 | 
 | ||||||
| def new_scene_from(name, src_scn=None, regen=True, crop=True, link_cam=True, link_light=True): | def new_scene_from(name, src_scn=None, regen=True, crop=True, link_cam=True, link_light=True): | ||||||
|     '''Get / Create a scene from name and source scene to get settings from''' |     '''Get / Create a scene from name and source scene to get settings from''' | ||||||
| @ -179,10 +207,11 @@ def get_render_scene(): | |||||||
|             render_scn.collection.objects.link(ob) |             render_scn.collection.objects.link(ob) | ||||||
| 
 | 
 | ||||||
|     render_scn.use_nodes = True |     render_scn.use_nodes = True | ||||||
|     # TODO Clear node tree (initial view layer stuff) |  | ||||||
|     # set adapted render settings (no AA) |  | ||||||
|     set_settings(render_scn) |  | ||||||
|      |      | ||||||
|  |     # TODO Clear node tree (initial view layer stuff) | ||||||
|  | 
 | ||||||
|  |     set_settings(render_scn, with_aa=False) # set adapted render settings (no AA by default) | ||||||
|  |     render_scn.use_aa = True     | ||||||
|     return render_scn |     return render_scn | ||||||
| 
 | 
 | ||||||
| def get_view_layer(name, scene=None): | def get_view_layer(name, scene=None): | ||||||
| @ -1054,8 +1083,8 @@ def split_object_to_scene(): | |||||||
|     coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera) |     coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera) | ||||||
|     if not coords: |     if not coords: | ||||||
|         return f'Scene "{scene_name}" created. But Border was not set (Timeout during GP analysis), should be done by hand if needed then use export crop to json' |         return f'Scene "{scene_name}" created. But Border was not set (Timeout during GP analysis), should be done by hand if needed then use export crop to json' | ||||||
|     set_border_region_from_coord(coords, margin=30, scn=new, export_json=True) |  | ||||||
|      |      | ||||||
|  |     set_border_region_from_coord(coords, margin=30, scn=new, export_json=True) | ||||||
|     export_crop_to_json() |     export_crop_to_json() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -1106,56 +1135,3 @@ def clear_frame_out_of_range_all_object(): | |||||||
|             ct += nct |             ct += nct | ||||||
|     print(f'{ct} gp frames deleted') |     print(f'{ct} gp frames deleted') | ||||||
|     return ct |     return ct | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| """ |  | ||||||
| def split_object_to_scene(): |  | ||||||
|     '''Create a new scene from selection''' |  | ||||||
| 
 |  | ||||||
|     # send objects in a new render scene |  | ||||||
|     ## define new scene name with active object names |  | ||||||
|     active = bpy.context.object |  | ||||||
|     scene_name = active.name |  | ||||||
|     objs = [o for o in bpy.context.selected_objects] |  | ||||||
|      |  | ||||||
|     rd_scn = bpy.data.scenes.get('Render') |  | ||||||
|     ## create scene and copy settings from render scene or current |  | ||||||
|     # src_scn = bpy.data.scenes.get('Render') |  | ||||||
|     # src_scn = src_scn or bpy.context.scene |  | ||||||
|     # if src_scn.name == scene_name: |  | ||||||
|     #     print('! Problem ! Trying to to create new render scene without source') |  | ||||||
|     #     return |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     ## From current scene (might be Render OR Scene) |  | ||||||
|     src_scn = bpy.context.scene |  | ||||||
| 
 |  | ||||||
|     new = new_scene_from(scene_name, src_scn=src_scn, regen=True) # crop=True, link_cam=True, link_light=True |  | ||||||
| 
 |  | ||||||
|     for ob in objs: |  | ||||||
|         new.collection.objects.link(ob) |  | ||||||
|         if ob.type == 'GPENCIL': |  | ||||||
|         # recreate VL |  | ||||||
|             vl_names = [l.viewlayer_render for l in ob.data.layers if l.viewlayer_render] |  | ||||||
|             for names in vl_names: |  | ||||||
|                 new.view_layers.new(names) |  | ||||||
|         # get_set_viewlayer_from_gp(ob, l, scene=new) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def set_crop_bbox_2d(ob, cam=None): |  | ||||||
|     '''Basic crop using bouding box on current frame''' |  | ||||||
|     from bpy_extras.object_utils import world_to_camera_view |  | ||||||
| 
 |  | ||||||
|     scn = bpy.context.scene  |  | ||||||
|     cam = cam or scn.camera |  | ||||||
|     # bbox = [ob.matrix_world @ Vector(b) for b in bbox_coords] |  | ||||||
|     coords2d = [world_to_camera_view(scn, cam, p) for p in get_bbox_3d(ob)] |  | ||||||
|          |  | ||||||
|     coords2d_x = sorted([c[0] for c in coords2d]) |  | ||||||
|     coords2d_y = sorted([c[1] for c in coords2d]) |  | ||||||
|     scn.render.border_min_x = coords2d_x[0] |  | ||||||
|     scn.render.border_max_x = coords2d_x[-1] |  | ||||||
|     scn.render.border_min_y = coords2d_y[0] |  | ||||||
|     scn.render.border_max_y = coords2d_y[-1] |  | ||||||
|     return |  | ||||||
| """ |  | ||||||
| @ -40,7 +40,11 @@ def add_rlayer(layer_name, scene=None, location=None, color=None, node_name=None | |||||||
|     return comp |     return comp | ||||||
| 
 | 
 | ||||||
| def connect_render_layer(rlayer, ng=None, out=None, frame=None): | def connect_render_layer(rlayer, ng=None, out=None, frame=None): | ||||||
|  |     if bpy.context.scene.name == 'Scene': | ||||||
|         scene = fn.get_render_scene() |         scene = fn.get_render_scene() | ||||||
|  |     else: | ||||||
|  |         scene = bpy.context.scene | ||||||
|  | 
 | ||||||
|     nodes = scene.node_tree.nodes |     nodes = scene.node_tree.nodes | ||||||
|     links = scene.node_tree.links |     links = scene.node_tree.links | ||||||
| 
 | 
 | ||||||
| @ -148,6 +152,9 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None): | |||||||
|         ngroup.links.new(ng_in.outputs[vl_name], aa.inputs[0]) # node_tree |         ngroup.links.new(ng_in.outputs[vl_name], aa.inputs[0]) # node_tree | ||||||
|         ngroup.links.new(aa.outputs[0], ng_out.inputs[vl_name]) # node_tree |         ngroup.links.new(aa.outputs[0], ng_out.inputs[vl_name]) # node_tree | ||||||
|          |          | ||||||
|  |         aa.mute = scene.use_aa # mute if native AA is used | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     fn.reorganise_NG_nodegroup(ng) # decorative |     fn.reorganise_NG_nodegroup(ng) # decorative | ||||||
| 
 | 
 | ||||||
|     # clean outputs |     # clean outputs | ||||||
| @ -210,8 +217,10 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None): | |||||||
| def get_set_viewlayer_from_gp(ob, l, scene=None): | def get_set_viewlayer_from_gp(ob, l, scene=None): | ||||||
|     '''setup ouptut from passed gp obj > layer''' |     '''setup ouptut from passed gp obj > layer''' | ||||||
|     if not scene: |     if not scene: | ||||||
|         # scene = bpy.context.scene |         if bpy.context.scene.name != 'Scene': | ||||||
|         scene = fn.get_render_scene() # create if necessary |             scene = bpy.context.scene | ||||||
|  |         else: | ||||||
|  |             scene = fn.get_render_scene() | ||||||
| 
 | 
 | ||||||
|     node_tree = scene.node_tree |     node_tree = scene.node_tree | ||||||
|     nodes = node_tree.nodes |     nodes = node_tree.nodes | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								ui.py
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								ui.py
									
									
									
									
									
								
							| @ -104,6 +104,7 @@ class GPEXP_PT_gp_node_ui(Panel): | |||||||
|         col.separator() |         col.separator() | ||||||
| 
 | 
 | ||||||
|         col.operator('gp.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER |         col.operator('gp.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER | ||||||
|  |         col.operator('gp.reset_render_settings', icon='SCENE', text='Reset All Scenes Render Settings') | ||||||
| 
 | 
 | ||||||
|         col.separator() |         col.separator() | ||||||
| 
 | 
 | ||||||
| @ -129,17 +130,20 @@ class GPEXP_PT_gp_node_ui(Panel): | |||||||
|         col.operator('gp.clear_render_tree', icon='X', text='Clear & Delete Render Scene').mode = "COMPLETE" |         col.operator('gp.clear_render_tree', icon='X', text='Clear & Delete Render Scene').mode = "COMPLETE" | ||||||
| 
 | 
 | ||||||
|         layout.separator() |         layout.separator() | ||||||
|         layout.label(text='Sub Scenes:') |         layout.label(text='Scenes:') | ||||||
|         layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selected Obj To Scene') |         layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selected Obj To Scene') | ||||||
| 
 | 
 | ||||||
|         row = layout.row(align=True) |         row = layout.row(align=True) | ||||||
|         row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop') |         row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop') | ||||||
|         row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json') |         row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json') | ||||||
| 
 | 
 | ||||||
|  |         layout.label(text='Render:') | ||||||
|         row = layout.row(align=True) |         row = layout.row(align=True) | ||||||
|         row.operator('gp.render_selected_scenes', icon='RENDER_ANIMATION', text='Render Selected Scene') |         row.operator('gp.render_selected_scenes', icon='RENDER_ANIMATION', text='Render Selected Scene') | ||||||
|  |         row.operator('gp.bg_render_script_selected_scenes', icon='TEXT', text='Gen Batch') | ||||||
|         # row.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All') |         # row.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All') | ||||||
| 
 | 
 | ||||||
|  |         layout.prop(context.scene, 'use_aa', text='Use Native AA Settings') | ||||||
|         layout.prop(prefs, 'advanced', text='Show Advanced Options') |         layout.prop(prefs, 'advanced', text='Show Advanced Options') | ||||||
|         # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'ALL' |         # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'ALL' | ||||||
|         # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'SELECTED' |         # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'SELECTED' | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user