Renumbering for already exported sequences

0.2.1

- feat: renumbering with keep existing values
main
Pullusb 2021-09-10 22:59:52 +02:00
parent 191f667b75
commit 07e5046bef
5 changed files with 152 additions and 115 deletions

View File

@ -9,6 +9,10 @@ OR always duplicate (safe but heavy scenes...)
if duplicate, need to "connect" with namespace ('_duprender') or something if duplicate, need to "connect" with namespace ('_duprender') or something
--> -->
0.2.1
- feat: renumbering with keep existing values
0.2.0 0.2.0
- feat: merge selected viewlayer - feat: merge selected viewlayer

View File

@ -36,7 +36,8 @@ class GPEXP_OT_number_outputs(bpy.types.Operator):
if self.ctrl: if self.ctrl:
fn.delete_numbering(fo) fn.delete_numbering(fo)
else: else:
fn.renumber(fo) fn.renumber_keep_existing(fo)
# fn.renumber(fo)
txt = 'de-numbered' if self.ctrl else 're-numbered' txt = 'de-numbered' if self.ctrl else 're-numbered'
if ct: if ct:

View File

@ -2,7 +2,7 @@ bl_info = {
"name": "GP exporter", "name": "GP exporter",
"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, 0), "version": (0, 2, 1),
"blender": (2, 93, 0), "blender": (2, 93, 0),
"location": "View3D", "location": "View3D",
"warning": "", "warning": "",

253
fn.py
View File

@ -279,7 +279,6 @@ def connect_to_group_input(n):
return val return val
return False return False
def clear_nodegroup_content_if_disconnected(ngroup): def clear_nodegroup_content_if_disconnected(ngroup):
'''Get a nodegroup.node_tree '''Get a nodegroup.node_tree
delete orphan nodes that are not connected from group input node delete orphan nodes that are not connected from group input node
@ -306,115 +305,6 @@ def random_color(alpha=False):
return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1), 1) return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1), 1)
return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1)) return (random.uniform(0,1), random.uniform(0,1), random.uniform(0,1))
def get_numbered_output(out, slot_name):
'''Return output slot name without looking for numbering ???_
'''
pattern = r'^(?:\d{3}_)?' # optional non capture group of 3 digits + _
pattern = f'{pattern}{slot_name}'
for inp in out.inputs:
if re.match(pattern, inp.name):
return inp
def add_fileslot_number(fs, number):
elems = fs.path.split('/')
for i, e in enumerate(elems):
if re.match(r'^\d{3}_', e):
elems[i] = re.sub(r'^(\d{3})', lambda x: str(number).zfill(3), e)
else:
elems[i] = f'{str(number).zfill(3)}_{e}'
new = '/'.join(elems)
fs.path = new
return new
def renumber(fo, offset=10):
'''Force renumber all the slots with a 3'''
if fo.type != 'OUTPUT_FILE': return
ct = 0
for fs in fo.file_slots:
add_fileslot_number(fs, ct)
ct += offset
def get_num(string):
num = re.search(r'^(\d{3})_', string)
if num:
return int(num.group(1))
"""
def renumber_keep(fo, offset=10):
'''Force renumber all the slots with a 3'''
if fo.type != 'OUTPUT_FILE': return
renum = re.compile(r'^(\d{3})_')
ct = 0
last_idx = len(fo.file_slots) -1
prev = None
prev_num = None
for idx, fs in enumerate(fo.file_slots):
# if idx!=last_idx:
# fs_next = fo.file_slots[idx+1]
if idx == last_idx: # handle last
if idx > 0:
prev = fo.file_slots[idx-1]
num = renum.search(prev)
if not num:
add_fileslot_number(fs, ct)
else:
add_fileslot_number(fs, int(num.group(1)) + offset)
else:
add_fileslot_number(fs, 0) # there is only one slot (maybe don't number ?)
break
# update the ct with the current taken number if any
number = renum.search(fs.path)
if number:
prev = fs
ct = number + offset
continue # skip already numbered
# analyse all next slots until there is numbered
divider = None
for i in range(idx + 1, len(fo.file_slots) - idx):
next_num = renum.search(fo.file_slots[idx + i])
if next_num:
divider = i-1
break
if idx == 0:
prev_num = 0
prev = None
else:
prev = fo.file_slots[idx-1]
prev_num = renum.search(prev.path)
if prev_num:
prev_num = prev_num.group(1)
if not divider: # just use prev and next if prev
if not prev:
add_fileslot_number(fs, ct)
# first check if it has a number (if not bas)
prev = fs
ct += offset
"""
def delete_numbering(fo): # padding=3
'''Delete prefix numbering on all slots on passed file output'''
if fo.type != 'OUTPUT_FILE': return
for fs in fo.file_slots:
elems = fs.path.split('/')
for i, e in enumerate(elems):
elems[i] = re.sub(r'^\d{3}_', '', e)
new = '/'.join(elems)
fs.path = new
def nodegroup_merge_inputs(ngroup): def nodegroup_merge_inputs(ngroup):
'''Get a nodegroup '''Get a nodegroup
merge every group inputs with alpha over merge every group inputs with alpha over
@ -453,3 +343,146 @@ def nodegroup_merge_inputs(ngroup):
# create one input and link # create one input and link
out = ngroup.outputs.new('NodeSocketColor', ngroup.inputs[0].name) out = ngroup.outputs.new('NodeSocketColor', ngroup.inputs[0].name)
ngroup.links.new(aa.outputs[0], ng_out.inputs[0]) ngroup.links.new(aa.outputs[0], ng_out.inputs[0])
## --- renumbering funcs ---
def get_numbered_output(out, slot_name):
'''Return output slot name without looking for numbering ???_
'''
pattern = r'^(?:\d{3}_)?' # optional non capture group of 3 digits + _
pattern = f'{pattern}{slot_name}'
for inp in out.inputs:
if re.match(pattern, inp.name):
return inp
def add_fileslot_number(fs, number):
elems = fs.path.split('/')
for i, e in enumerate(elems):
if re.match(r'^\d{3}_', e):
elems[i] = re.sub(r'^(\d{3})', lambda x: str(number).zfill(3), e)
else:
elems[i] = f'{str(number).zfill(3)}_{e}'
new = '/'.join(elems)
fs.path = new
return new
def renumber(fo, offset=10):
'''Force renumber all the slots with a 3'''
if fo.type != 'OUTPUT_FILE': return
ct = 10 # start at 10
for fs in fo.file_slots:
add_fileslot_number(fs, ct)
ct += offset
def get_num(string) -> int:
'''get a tring or a file_slot object
return leading number or None
'''
if not isinstance(string, str):
string = string.path
num = re.search(r'^(\d{3})_', string)
if num:
return int(num.group(1))
def delete_numbering(fo): # padding=3
'''Delete prefix numbering on all slots on passed file output'''
if fo.type != 'OUTPUT_FILE': return
for fs in fo.file_slots:
elems = fs.path.split('/')
for i, e in enumerate(elems):
elems[i] = re.sub(r'^\d{3}_', '', e)
new = '/'.join(elems)
fs.path = new
def renumber_keep_existing(fo, offset=10):
'''Renumber by keeping existing numbers and inserting new one whenever possible
Big and ugly function that do the trick nonetheless...
'''
if fo.type != 'OUTPUT_FILE': return
ct = 10
fsl = fo.file_slots
last_idx = len(fsl) - 1
prev = None
prev_num = None
for idx, fs in enumerate(fsl):
print('-->', idx, fs.path)
if idx == last_idx: # handle last
if idx > 0:
prev = fsl[idx-1]
num = get_num(prev)
if num is not None:
break
else:
add_fileslot_number(fs, ct)
else:
add_fileslot_number(fs, 10) # there is only one slot (maybe don't number ?)
break
# update the ct with the current taken number if any
number = get_num(fs)
if number is not None:
prev = fs
ct = number + offset
continue # skip already numbered
# analyse all next slots until there is numbered
divider = 0
print(f'range(1, {len(fsl) - idx}')
for i in range(1, len(fsl) - idx):
print('i >> idx + i', i, idx + i)
next_num = get_num(fsl[idx + i])
print('next_num: ', next_num)
if next_num is not None:
divider = i+1
break
if idx == 0: # handle first
prev_num = 0
prev = None
if next_num is None:
add_fileslot_number(fs, 0)
elif next_num == 0:
print(f'Cannot insert value before 0 to {fsl.path}')
continue
else:
add_fileslot_number(fs, int(next_num / 2))
else:
prev = fsl[idx-1]
test_prev = get_num(prev)
if test_prev is not None:
prev_num = test_prev
if not divider:
if prev_num is not None:
add_fileslot_number(fs, prev_num + offset)
else:
add_fileslot_number(fs, ct)
else:
print('divider: ', divider)
if prev_num is not None:
print('in updater')
# iterate rename
gap_inc = int((next_num - prev_num) / divider)
print('gap_inc: ', gap_inc)
if gap_inc < 1: # same values !
print(f'cannot insert a median value at {fs.path} between {prev_num} and {next_num}')
continue
ct = prev_num
for temp_id in range(idx, idx+i):
ct += gap_inc
add_fileslot_number(fsl[temp_id], ct)
else:
print("what's going on ?\n")
# first check if it has a number (if not bas)
prev = fs
ct += offset

3
ui.py
View File

@ -44,9 +44,8 @@ class GPEXP_PT_gp_node_ui(Panel):
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.separator() col.separator()
col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber outputs')
## maybe get only this one...
col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber Selected outputs').mode = 'SELECTED' col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber Selected outputs').mode = 'SELECTED'
# col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber outputs').mode = 'ALL'
layout.separator() layout.separator()