Renumbering for already exported sequences
0.2.1 - feat: renumbering with keep existing values
This commit is contained in:
		
							parent
							
								
									191f667b75
								
							
						
					
					
						commit
						07e5046bef
					
				| @ -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 | ||||||
|  | |||||||
| @ -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: | ||||||
|  | |||||||
| @ -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
									
									
									
									
									
								
							
							
						
						
									
										253
									
								
								fn.py
									
									
									
									
									
								
							| @ -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
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ui.py
									
									
									
									
									
								
							| @ -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() | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user