Add popup with option to select duplicated strokes instead of removing

This commit is contained in:
pullusb 2025-06-17 18:01:01 +02:00
parent e93ee458b9
commit 2b198d03c9

View File

@ -10,9 +10,10 @@ from bpy.props import (BoolProperty,
CollectionProperty, CollectionProperty,
StringProperty) StringProperty)
def remove_stroke_exact_duplications(apply=True, verbose=True): def remove_stroke_exact_duplications(apply=True, verbose=True, select=False):
'''Remove accidental stroke duplication (points exactly in the same place) '''Remove accidental stroke duplication (points exactly in the same place)
:apply: Remove the duplication instead of just listing dupes :apply: Remove the duplication instead of just listing dupes
:select: Select the duplicated strokes instead of removing them (disabled by apply)
return number of duplication found/deleted return number of duplication found/deleted
''' '''
# TODO: Add additional check of material (even if unlikely to happen, better to avoid false positive) # TODO: Add additional check of material (even if unlikely to happen, better to avoid false positive)
@ -25,20 +26,25 @@ def remove_stroke_exact_duplications(apply=True, verbose=True):
for f in l.frames: for f in l.frames:
stroke_list = [] stroke_list = []
idx_to_delete = [] idx_to_delete = []
for idx, s in enumerate(f.drawing.strokes): for idx, s in enumerate(f.drawing.strokes):
point_list = [p.position.copy() for p in s.points] point_list = [p.position.copy() for p in s.points]
if point_list in stroke_list: if point_list in stroke_list:
ct += 1 ct += 1
idx_to_delete.append(idx) idx_to_delete.append(idx)
if not apply and select:
s.select = True
else: else:
stroke_list.append(point_list) stroke_list.append(point_list)
if not apply and select:
if apply and idx_to_delete: s.select = False
# Remove redundancy (carefull, passing an empty list delete all strokes)
if idx_to_delete:
if verbose: if verbose:
print(f"{gp.name} > {l.name} > frame {f.frame_number}: {len(idx_to_delete)} strokes") print(f"{gp.name} > {l.name} > frame {f.frame_number}: {len(idx_to_delete)} strokes")
f.drawing.remove_strokes(indices=idx_to_delete) if apply:
# Remove redundancy (carefull, passing an empty list delete all strokes)
f.drawing.remove_strokes(indices=idx_to_delete)
return ct return ct
class GPTB_OT_remove_stroke_duplication(bpy.types.Operator): class GPTB_OT_remove_stroke_duplication(bpy.types.Operator):
@ -47,12 +53,31 @@ class GPTB_OT_remove_stroke_duplication(bpy.types.Operator):
bl_description = "Within every frame, remove every strokes that are exactly superposed with a previous one" bl_description = "Within every frame, remove every strokes that are exactly superposed with a previous one"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
apply : bpy.props.BoolProperty(name="Apply Fixes", default=True, apply : bpy.props.BoolProperty(name="Remove Stroke", default=True,
description="Remove the duplication", description="Remove the duplication, else list only",
options={'SKIP_SAVE'}) options={'SKIP_SAVE'})
select : bpy.props.BoolProperty(name="Select Duplicated Strokes", default=False)
def invoke(self, context, event):
# self.file_dump = event.ctrl
return context.window_manager.invoke_props_dialog(self) # , width=400
# return self.execute(context)
def draw(self, context):
layout=self.layout
layout.use_property_split = True
col = layout.column()
col.prop(self, 'apply')
row=col.row(align=True)
row.prop(self, 'select')
row.enabled = not self.apply
if not self.apply and not self.select:
col.label(text="Only list in console and report number of duplications", icon='INFO')
def execute(self, context): def execute(self, context):
ct = remove_stroke_exact_duplications(apply=self.apply) ct = remove_stroke_exact_duplications(apply=self.apply, select=self.select, verbose=True)
if ct > 0: if ct > 0:
if self.apply: if self.apply:
self.report({'INFO'}, f'Removed {ct} strokes duplications') self.report({'INFO'}, f'Removed {ct} strokes duplications')