fixes new merge lower name node format
0.3.0 - fix: viewlayer exclude attribution error - fix: force PNG 8bit 15% compression for output settings - change: GP dopesheet merge ops -> viewlayer merge instead of creating alphaover node - feat: batch to_lower name - feat: copy active output node format to selectedmain
parent
9044134d79
commit
556612664d
|
@ -12,6 +12,14 @@ Activate / deactivate layer opaticty according to prefix
|
||||||
Activate / deactivate all masks using MA layers
|
Activate / deactivate all masks using MA layers
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
0.3.0
|
||||||
|
|
||||||
|
- fix: viewlayer exclude attribution error
|
||||||
|
- fix: force PNG 8bit 15% compression for output settings
|
||||||
|
- change: GP dopesheet merge ops -> viewlayer merge instead of creating alphaover node
|
||||||
|
- feat: batch to_lower name
|
||||||
|
- feat: copy active output node format to selected
|
||||||
|
|
||||||
0.2.8
|
0.2.8
|
||||||
|
|
||||||
- fix: added AA nodegroup
|
- fix: added AA nodegroup
|
||||||
|
|
|
@ -27,7 +27,7 @@ class GPEXP_OT_add_layer_to_render(bpy.types.Operator):
|
||||||
if not l.select:
|
if not l.select:
|
||||||
if not l.viewlayer_render:
|
if not l.viewlayer_render:
|
||||||
# TODO : need to link, can reaise error if object is not linked in Render scene yet
|
# TODO : need to link, can reaise error if object is not linked in Render scene yet
|
||||||
l.viewlayer_render == fn.get_view_layer('exclude')
|
l.viewlayer_render == fn.get_view_layer('exclude').name
|
||||||
continue
|
continue
|
||||||
gen_vlayer.get_set_viewlayer_from_gp(ob, l)
|
gen_vlayer.get_set_viewlayer_from_gp(ob, l)
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ 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') # assign "exclude"
|
l.viewlayer_render = fn.get_view_layer('exclude').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=fn.get_render_scene())
|
||||||
|
|
|
@ -22,8 +22,48 @@ class GPEXP_OT_mute_toggle_output_nodes(bpy.types.Operator):
|
||||||
self.report({"INFO"}, f'{ct} nodes {state}')
|
self.report({"INFO"}, f'{ct} nodes {state}')
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class GPEXP_OT_set_output_node_format(bpy.types.Operator):
|
||||||
|
bl_idname = "gp.set_output_node_format"
|
||||||
|
bl_label = "Set output format from active"
|
||||||
|
bl_description = "Change all selected output node to match active output node format"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
mute : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
# scene = bpy.data.scenes.get('Render')
|
||||||
|
nodes = context.scene.node_tree.nodes
|
||||||
|
if not nodes.active or nodes.active.type != 'OUTPUT_FILE':
|
||||||
|
self.report({"ERROR"}, f'Active node should be an output file to use as reference for output format')
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
ref = nodes.active
|
||||||
|
color_mode = ref.format.color_mode
|
||||||
|
file_format = ref.format.file_format
|
||||||
|
color_depth = ref.format.color_depth
|
||||||
|
compression = ref.format.compression
|
||||||
|
|
||||||
|
ct = 0
|
||||||
|
for n in context.scene.node_tree.nodes:
|
||||||
|
if n.type != 'OUTPUT_FILE' or n == ref:
|
||||||
|
continue
|
||||||
|
|
||||||
|
n.format.color_mode = color_mode
|
||||||
|
n.format.file_format = file_format
|
||||||
|
n.format.color_depth = color_depth
|
||||||
|
n.format.compression = compression
|
||||||
|
|
||||||
|
ct += 1
|
||||||
|
|
||||||
|
# state = 'muted' if self.mute else 'unmuted'
|
||||||
|
self.report({"INFO"}, f'{ct} output format copied from {ref.name}')
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
GPEXP_OT_mute_toggle_output_nodes,
|
GPEXP_OT_mute_toggle_output_nodes,
|
||||||
|
GPEXP_OT_set_output_node_format,
|
||||||
)
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|
|
@ -95,6 +95,7 @@ def merge_layers(rlayers, obname=None, active=None, disconnect=True, color=None)
|
||||||
# create dedicated fileout
|
# create dedicated fileout
|
||||||
|
|
||||||
out = fn.create_node('CompositorNodeOutputFile', tree=node_tree, location=(ng.location[0]+450, ng.location[1]+50), width=600)
|
out = fn.create_node('CompositorNodeOutputFile', tree=node_tree, location=(ng.location[0]+450, ng.location[1]+50), width=600)
|
||||||
|
fn.set_file_output_format(out)
|
||||||
out_name = f'merge_OUT_{vl_name}' # or get output from frame
|
out_name = f'merge_OUT_{vl_name}' # or get output from frame
|
||||||
out.name = out_name
|
out.name = out_name
|
||||||
out.base_path = base_path
|
out.base_path = base_path
|
||||||
|
@ -111,9 +112,90 @@ def merge_layers(rlayers, obname=None, active=None, disconnect=True, color=None)
|
||||||
|
|
||||||
return ng, out
|
return ng, out
|
||||||
|
|
||||||
|
class GPEXP_OT_merge_viewlayers_to_active(bpy.types.Operator):
|
||||||
|
bl_idname = "gp.merge_viewlayers_to_active"
|
||||||
|
bl_label = "Merge selected layers view_layers"
|
||||||
|
bl_description = "Merge view layers of selected gp layers to on the active one"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.object and context.object.type == 'GPENCIL'
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
ob = bpy.context.object
|
||||||
|
# layers = [l for l in ob.data.layers if l.select and not l.hide]
|
||||||
|
act = ob.data.layers.active
|
||||||
|
layers = [l for l in ob.data.layers if l.select and l != act]
|
||||||
|
|
||||||
|
if not act.viewlayer_render:
|
||||||
|
self.report({'ERROR'}, f'Active layer {act.info} has no viewlayer assigned')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
rd_scn = bpy.data.scenes.get('Render')
|
||||||
|
if not rd_scn:
|
||||||
|
self.report({'ERROR'}, 'Viewlayers needs to be generated first!')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
# list layers and viewlayers
|
||||||
|
vls = [rd_scn.view_layers.get(l.viewlayer_render) for l in layers
|
||||||
|
if l.viewlayer_render and l.viewlayer_render != act.viewlayer_render and rd_scn.view_layers.get(l.viewlayer_render)]
|
||||||
|
|
||||||
|
vl_names = [v.name for v in vls]
|
||||||
|
|
||||||
|
for n in reversed(rd_scn.node_tree.nodes):
|
||||||
|
if n.type == 'R_LAYERS' and n.layer in vl_names:
|
||||||
|
for lnk in n.outputs[0].links:
|
||||||
|
grp = lnk.to_node
|
||||||
|
if grp.type != 'GROUP':
|
||||||
|
continue
|
||||||
|
if not grp.name.startswith('NG'):
|
||||||
|
continue
|
||||||
|
sockin = lnk.to_socket
|
||||||
|
sockout = grp.outputs.get(sockin.name)
|
||||||
|
if not sockout:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for grplink in sockout.links:
|
||||||
|
if grplink.to_node.type != 'OUTPUT_FILE':
|
||||||
|
continue
|
||||||
|
fo_socket = grplink.to_socket
|
||||||
|
fo = grplink.to_node
|
||||||
|
fo.file_slots.remove(fo_socket)
|
||||||
|
|
||||||
|
# remove input and output from group
|
||||||
|
# grp.inputs.remove(sockin) # do not clear inside !!
|
||||||
|
# grp.outputs.remove(sockout) # do not clear inside !!
|
||||||
|
ngroup = grp.node_tree
|
||||||
|
for i in range(len(grp.inputs))[::-1]:
|
||||||
|
if grp.inputs[i].name == sockin.name:
|
||||||
|
ngroup.inputs.remove(ngroup.inputs[i])
|
||||||
|
break
|
||||||
|
for i in range(len(grp.outputs))[::-1]:
|
||||||
|
if grp.outputs[i].name == sockout.name:
|
||||||
|
ngroup.outputs.remove(ngroup.outputs[i])
|
||||||
|
break
|
||||||
|
|
||||||
|
# remove render_layer node
|
||||||
|
rd_scn.node_tree.nodes.remove(n)
|
||||||
|
|
||||||
|
# assign view layer from active to selected
|
||||||
|
for l in layers:
|
||||||
|
l.viewlayer_render = act.viewlayer_render
|
||||||
|
|
||||||
|
## delete unused_vl
|
||||||
|
|
||||||
|
# used_vl_name = [n.layer for n in rd_scn.node_tree.nodes if n.type == 'R_LAYERS' and n.layer]
|
||||||
|
for vl in vls:
|
||||||
|
rd_scn.view_layers.remove(vl)
|
||||||
|
# if not vl.name in used_vl_name:
|
||||||
|
# rd_scn.view_layers.remove(vl)
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
class GPEXP_OT_merge_selected_dopesheet_layers(bpy.types.Operator):
|
class GPEXP_OT_merge_selected_dopesheet_layers(bpy.types.Operator):
|
||||||
bl_idname = "gp.merge_selected_dopesheet_layers"
|
bl_idname = "gp.merge_selected_dopesheet_layers"
|
||||||
bl_label = "Merge selected layers view_layers "
|
bl_label = "Merge selected layers nodes"
|
||||||
bl_description = "Merge view layers of selected gp layers to a new dedicated file output"
|
bl_description = "Merge view layers of selected gp layers to a new dedicated file output"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
@ -124,10 +206,10 @@ class GPEXP_OT_merge_selected_dopesheet_layers(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):
|
||||||
# merge_selected_layers() # function to merge from GP dopesheet
|
|
||||||
ob = bpy.context.object
|
ob = bpy.context.object
|
||||||
layers = [l for l in ob.data.layers if l.select and not l.hide]
|
layers = [l for l in ob.data.layers if l.select and not l.hide]
|
||||||
act = ob.data.layers.active
|
act = ob.data.layers.active
|
||||||
|
# merge_selected_layers() # function to merge from GP dopesheet
|
||||||
if not act:
|
if not act:
|
||||||
self.report({'ERROR'}, f'An active layer is needed to set merge output name')
|
self.report({'ERROR'}, f'An active layer is needed to set merge output name')
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
@ -199,14 +281,16 @@ class GPEXP_OT_merge_selected_viewlayer_nodes(bpy.types.Operator):
|
||||||
if not all(selection[0].layer.split('.')[0] == n.layer.split('.')[0] for n in selection):
|
if not all(selection[0].layer.split('.')[0] == n.layer.split('.')[0] for n in selection):
|
||||||
print('/!\ Merge -> Not every nodes start with the same object')
|
print('/!\ Merge -> Not every nodes start with the same object')
|
||||||
|
|
||||||
# obname = selection[0].layer.split('.')[0]
|
color = None
|
||||||
merge_layers(selection, active=nodes.active, disconnect=self.disconnect)
|
if nodes.active.use_custom_color and nodes.active.color:
|
||||||
|
color = nodes.active.color
|
||||||
|
merge_layers(selection, active=nodes.active, disconnect=self.disconnect, color=color)
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
GPEXP_OT_merge_selected_dopesheet_layers,
|
GPEXP_OT_merge_viewlayers_to_active,
|
||||||
|
GPEXP_OT_merge_selected_dopesheet_layers,# unused
|
||||||
GPEXP_OT_merge_selected_viewlayer_nodes,
|
GPEXP_OT_merge_selected_viewlayer_nodes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,118 @@ class GPEXP_OT_layers_state(bpy.types.Operator):
|
||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
PATTERN = r'^(?P<grp>-\s)?(?P<tag>[A-Z]{2}_)?(?P<name>.*?)(?P<sfix>_[A-Z]{2})?(?P<inc>\.\d{3})?$' # numering
|
||||||
|
def lower_layer_name(layer, prefix='', desc='', suffix=''):
|
||||||
|
'''GET a layer and argumen to build and assign name'''
|
||||||
|
import re
|
||||||
|
|
||||||
|
name = layer.info
|
||||||
|
|
||||||
|
pattern = PATTERN
|
||||||
|
sep = '_'
|
||||||
|
res = re.search(pattern, name.strip())
|
||||||
|
|
||||||
|
|
||||||
|
grp = '' if res.group('grp') is None else res.group('grp')
|
||||||
|
tag = '' if res.group('tag') is None else res.group('tag')
|
||||||
|
# tag2 = '' if res.group('tag2') is None else res.group('tag2')
|
||||||
|
name = '' if res.group('name') is None else res.group('name')
|
||||||
|
sfix = '' if res.group('sfix') is None else res.group('sfix')
|
||||||
|
inc = '' if res.group('inc') is None else res.group('inc')
|
||||||
|
|
||||||
|
if grp:
|
||||||
|
grp = ' ' + grp # name is strip(), so grp first spaces are gones.
|
||||||
|
|
||||||
|
if prefix:
|
||||||
|
if prefix == 'prefixkillcode':
|
||||||
|
tag = ''
|
||||||
|
else:
|
||||||
|
tag = prefix.upper().strip() + sep
|
||||||
|
# if prefix2:
|
||||||
|
# tag2 = prefix2.upper().strip() + sep
|
||||||
|
if desc:
|
||||||
|
name = desc
|
||||||
|
|
||||||
|
if suffix:
|
||||||
|
if suffix == 'suffixkillcode':
|
||||||
|
sfix = ''
|
||||||
|
else:
|
||||||
|
sfix = sep + suffix.upper().strip()
|
||||||
|
|
||||||
|
# check if name is available without the increment ending
|
||||||
|
new = f'{grp}{tag}{name.lower()}{sfix}' # lower suffix ?
|
||||||
|
|
||||||
|
if new != layer.info:
|
||||||
|
print(f'{layer.info} >> new')
|
||||||
|
layer.info = new
|
||||||
|
|
||||||
|
class GPEXP_OT_lower_layers_name(bpy.types.Operator):
|
||||||
|
bl_idname = "gp.lower_layers_name"
|
||||||
|
bl_label = "Lower Layers Name"
|
||||||
|
bl_description = "Make the layer name lowercase without touching prefix and suffix"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.object and context.object.type == 'GPENCIL'
|
||||||
|
|
||||||
|
all_objects : BoolProperty(name='On All Object',
|
||||||
|
default=False, description='On All object, else use selected objects') # , options={'SKIP_SAVE'}
|
||||||
|
|
||||||
|
object_name : BoolProperty(name='Lower Object Name',
|
||||||
|
default=True, description='Make the object name lowercase') # , options={'SKIP_SAVE'}
|
||||||
|
|
||||||
|
layer_name : BoolProperty(name='Lower Layers Names',
|
||||||
|
default=True, description='Make the layers name lowercase') # , options={'SKIP_SAVE'}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
# self.ctrl=event.ctrl
|
||||||
|
# self.alt=event.alt
|
||||||
|
if event.alt:
|
||||||
|
self.all_objects=True
|
||||||
|
# return self.execute(context)
|
||||||
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.prop(self, 'all_objects')
|
||||||
|
if self.all_objects:
|
||||||
|
gp_ct = len([o for o in context.scene.objects if o.type == 'GPENCIL'])
|
||||||
|
else:
|
||||||
|
gp_ct = len([o for o in context.selected_objects if o.type == 'GPENCIL'])
|
||||||
|
|
||||||
|
layout.label(text=f'{gp_ct} to lower-case')
|
||||||
|
layout.separator()
|
||||||
|
layout.label(text=f'Choose what to rename:')
|
||||||
|
layout.prop(self, 'object_name')
|
||||||
|
layout.prop(self, 'layer_name')
|
||||||
|
if not self.object_name and not self.layer_name:
|
||||||
|
layout.label(text=f'At least one choice!', icon='ERROR')
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if self.all_objects:
|
||||||
|
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||||
|
else:
|
||||||
|
pool = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||||
|
|
||||||
|
for ob in pool:
|
||||||
|
|
||||||
|
if self.object_name:
|
||||||
|
rename_data = ob.name == ob.data.name
|
||||||
|
ob.name = ob.name.lower()
|
||||||
|
if rename_data:
|
||||||
|
ob.data.name = ob.data.name.lower()
|
||||||
|
|
||||||
|
if self.layer_name:
|
||||||
|
for l in ob.data.layers:
|
||||||
|
lower_layer_name(l)
|
||||||
|
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
classes=(
|
classes=(
|
||||||
GPEXP_OT_layers_state,
|
GPEXP_OT_layers_state,
|
||||||
|
GPEXP_OT_lower_layers_name
|
||||||
)
|
)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
|
|
@ -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, 2, 8),
|
"version": (0, 3, 0),
|
||||||
"blender": (2, 93, 0),
|
"blender": (2, 93, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
31
fn.py
31
fn.py
|
@ -37,22 +37,27 @@ def create_aa_nodegroup(tree):
|
||||||
ng_in = create_node('NodeGroupInput', tree=ngroup, location=(-600,0))
|
ng_in = create_node('NodeGroupInput', tree=ngroup, location=(-600,0))
|
||||||
ng_out = create_node('NodeGroupOutput', tree=ngroup, location=(600,0))
|
ng_out = create_node('NodeGroupOutput', tree=ngroup, location=(600,0))
|
||||||
|
|
||||||
sep = create_node('CompositorNodeSepRGBA', tree=ngroup, location=(-300,0))
|
sep = create_node('CompositorNodeSepRGBA', tree=ngroup, location=(-150,0))
|
||||||
comb = create_node('CompositorNodeCombRGBA', tree=ngroup, location=(200,25))
|
comb = create_node('CompositorNodeCombRGBA', tree=ngroup, location=(350,25))
|
||||||
ngroup.links.new(ng_in.outputs[0], sep.inputs[0])
|
|
||||||
|
# in AA
|
||||||
|
# ngroup.links.new(comb.outputs[0], ng_out.inputs[0]) # <- connect without out AA
|
||||||
|
aa = new_aa_node(ngroup, location=(-400, 0))
|
||||||
|
# ngroup.links.new(ng_in.outputs[0], sep.inputs[0])
|
||||||
|
ngroup.links.new(ng_in.outputs[0], aa.inputs[0])
|
||||||
|
ngroup.links.new(aa.outputs[0], sep.inputs[0])
|
||||||
|
|
||||||
|
# ngroup.links.new(ng_in.outputs[0], sep.inputs[0])
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
ngroup.links.new(sep.outputs[i], comb.inputs[i])
|
ngroup.links.new(sep.outputs[i], comb.inputs[i])
|
||||||
|
|
||||||
# alpha AA
|
# alpha AA
|
||||||
alpha_aa = new_aa_node(ngroup, location=(-50,-150))
|
alpha_aa = new_aa_node(ngroup, location=(100,-150))
|
||||||
ngroup.links.new(sep.outputs[3], alpha_aa.inputs[0])
|
ngroup.links.new(sep.outputs[3], alpha_aa.inputs[0])
|
||||||
ngroup.links.new(alpha_aa.outputs[0], comb.inputs[3])
|
ngroup.links.new(alpha_aa.outputs[0], comb.inputs[3])
|
||||||
|
|
||||||
# outpout AA (maybe externalize ?)
|
ngroup.links.new(comb.outputs[0], ng_out.inputs[0])
|
||||||
# ngroup.links.new(comb.outputs[0], ng_out.inputs[0]) # <- connect without out AA
|
|
||||||
aa = new_aa_node(ngroup, location=(380, 0))
|
|
||||||
ngroup.links.new(comb.outputs[0], aa.inputs[0])
|
|
||||||
ngroup.links.new(aa.outputs[0], ng_out.inputs[0])
|
|
||||||
|
|
||||||
|
|
||||||
ng = create_node('CompositorNodeGroup', tree=tree)
|
ng = create_node('CompositorNodeGroup', tree=tree)
|
||||||
|
@ -88,6 +93,12 @@ def copy_settings(obj_a, obj_b):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def set_file_output_format(fo):
|
||||||
|
fo.format.color_mode = 'RGBA'
|
||||||
|
fo.format.file_format = 'PNG'
|
||||||
|
fo.format.color_depth = '8'
|
||||||
|
fo.format.compression = 15
|
||||||
|
|
||||||
def set_settings(scene=None):
|
def set_settings(scene=None):
|
||||||
if not scene:
|
if not scene:
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
|
@ -408,7 +419,7 @@ def nodegroup_merge_inputs(ngroup):
|
||||||
prev = ao
|
prev = ao
|
||||||
|
|
||||||
## create a merged name as output ??
|
## create a merged name as output ??
|
||||||
aa = new_aa_node(ngroup)
|
aa = create_aa_nodegroup(ngroup) # new_aa_node(ngroup)
|
||||||
aa.location = (ao.location.x + 200, ao.location.y)
|
aa.location = (ao.location.x + 200, ao.location.y)
|
||||||
ngroup.links.new(ao.outputs[0], aa.inputs[0]) # node_tree
|
ngroup.links.new(ao.outputs[0], aa.inputs[0]) # node_tree
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@ def connect_render_layer(rlayer, ng=None, out=None, frame=None):
|
||||||
if not out:
|
if not out:
|
||||||
# color = (0.2,0.3,0.5)
|
# color = (0.2,0.3,0.5)
|
||||||
out = fn.create_node('CompositorNodeOutputFile', tree=scene.node_tree, location=(fn.real_loc(ng)[0]+500, fn.real_loc(ng)[1]+50), width=600) # =(ng.location[0]+600, ng.location[1]+50)
|
out = fn.create_node('CompositorNodeOutputFile', tree=scene.node_tree, location=(fn.real_loc(ng)[0]+500, fn.real_loc(ng)[1]+50), width=600) # =(ng.location[0]+600, ng.location[1]+50)
|
||||||
|
fn.set_file_output_format(out)
|
||||||
out.name = out_name
|
out.name = out_name
|
||||||
out.parent = frame
|
out.parent = frame
|
||||||
out.base_path = f'//render/{bpy.path.clean_name(obname)}'
|
out.base_path = f'//render/{bpy.path.clean_name(obname)}'
|
||||||
|
|
8
ui.py
8
ui.py
|
@ -60,6 +60,9 @@ class GPEXP_PT_gp_node_ui(Panel):
|
||||||
subcol.operator('gp.number_outputs', icon='LINENUMBERS_ON', text=txt).mode = 'SELECTED'
|
subcol.operator('gp.number_outputs', icon='LINENUMBERS_ON', text=txt).mode = 'SELECTED'
|
||||||
# col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber all outputs').mode = 'ALL'
|
# col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber all outputs').mode = 'ALL'
|
||||||
|
|
||||||
|
subcol.operator('gp.set_output_node_format', icon='OUTPUT', text='Copy Active Output Format')
|
||||||
|
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
col=layout.column()
|
col=layout.column()
|
||||||
|
@ -91,6 +94,8 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.label(text=f'Multiple users ({context.object.data.users})', icon='ERROR')
|
row.label(text=f'Multiple users ({context.object.data.users})', icon='ERROR')
|
||||||
row.operator("wm.call_menu", text="", icon='QUESTION').name = "GPEXP_MT_multi_user_doc"
|
row.operator("wm.call_menu", text="", icon='QUESTION').name = "GPEXP_MT_multi_user_doc"
|
||||||
|
layout.label(text=f'viewlayer: {context.object.data.layers.active.viewlayer_render}')
|
||||||
|
|
||||||
|
|
||||||
## On layers
|
## On layers
|
||||||
if context.object and context.object.type == 'GPENCIL':
|
if context.object and context.object.type == 'GPENCIL':
|
||||||
|
@ -105,7 +110,7 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
|
||||||
ct = len([l for l in context.object.data.layers if l.select])
|
ct = len([l for l in context.object.data.layers if l.select])
|
||||||
txt = f'Merge {ct} layers'
|
txt = f'Merge {ct} layers'
|
||||||
# merge layers from dopesheet
|
# merge layers from dopesheet
|
||||||
row.operator('gp.merge_selected_dopesheet_layers', text=txt, icon='SELECT_EXTEND')
|
row.operator('gp.merge_viewlayers_to_active', text=txt, icon='SELECT_EXTEND')
|
||||||
row.enabled= ct > 1
|
row.enabled= ct > 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,6 +126,7 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
layout.operator('gp.layers_state', icon='CHECKMARK', text='Check layers')
|
layout.operator('gp.layers_state', icon='CHECKMARK', text='Check layers')
|
||||||
|
layout.operator('gp.lower_layers_name', icon='SYNTAX_OFF', text='Rename Lowercase')
|
||||||
|
|
||||||
# row = layout.row()
|
# row = layout.row()
|
||||||
layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors')
|
layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors')
|
||||||
|
|
Loading…
Reference in New Issue