merge stroke-point del into one ops - add in menu
This commit is contained in:
parent
93b7ad91d8
commit
a86a1fd409
@ -3,9 +3,11 @@
|
||||
4.2.0
|
||||
|
||||
- added: Delete Grease pencil strokes or points view bound (selection outside of viewport region is untouched)
|
||||
- No preset shortcut:
|
||||
- `gp.delete_points_view_bound` for points
|
||||
- `gp.delete_strokes_view_bound` for strokes
|
||||
- No preset shortcut
|
||||
<!-- - `grease_pencil.delete_points_view_bound` for points -->
|
||||
<!-- - `grease_pencil.delete_strokes_view_bound` for strokes -->
|
||||
- `grease_pencil.delete_view_bound`
|
||||
- Added to Delete menu (au)
|
||||
|
||||
4.1.3
|
||||
|
||||
|
@ -24,9 +24,9 @@ def is_stroke_in_view(stroke, matrix, region, region_3d):
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class GPT_OT_delete_strokes_view_bound(bpy.types.Operator):
|
||||
bl_idname = "gp.delete_strokes_view_bound"
|
||||
""" # separated operators for strokes and points
|
||||
class GP_OT_delete_strokes_view_bound(bpy.types.Operator):
|
||||
bl_idname = "grease_pencil.delete_strokes_view_bound"
|
||||
bl_label = "Delete Strokes View Bound "
|
||||
bl_description = "Delete all selected strokes in view only"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
@ -77,8 +77,8 @@ class GPT_OT_delete_strokes_view_bound(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class GPT_OT_delete_points_view_bound(bpy.types.Operator):
|
||||
bl_idname = "gp.delete_points_view_bound"
|
||||
class GP_OT_delete_points_view_bound(bpy.types.Operator):
|
||||
bl_idname = "grease_pencil.delete_points_view_bound"
|
||||
bl_label = "Delete Points View Bound"
|
||||
bl_description = "Delete all selected points in view only"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
@ -155,15 +155,111 @@ class GPT_OT_delete_points_view_bound(bpy.types.Operator):
|
||||
drawing.remove_strokes(indices=stroke_indices_to_delete)
|
||||
|
||||
if avoid_ct:
|
||||
self.report({'INFO'}, f"Skipped {avoid_ct} strokes not in view")
|
||||
self.report({'WARNING'}, f"Skipped {avoid_ct} strokes not in view")
|
||||
return {'FINISHED'}
|
||||
"""
|
||||
class GP_OT_delete_view_bound(bpy.types.Operator):
|
||||
bl_idname = "grease_pencil.delete_view_bound"
|
||||
bl_label = "Delete View Bound"
|
||||
bl_description = "Delete all selected strokes / points only if there are in view (current viewport region)"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
# def invoke(self, context, event):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.mode == 'EDIT_GREASE_PENCIL'
|
||||
|
||||
def execute(self, context):
|
||||
gp = context.grease_pencil
|
||||
if not gp:
|
||||
self.report({'ERROR'}, "No Grease Pencil object found")
|
||||
return {'CANCELLED'}
|
||||
|
||||
ob = context.object
|
||||
if not ob or ob.type != 'GREASEPENCIL':
|
||||
self.report({'ERROR'}, "Active object is not a Grease Pencil object")
|
||||
return {'CANCELLED'}
|
||||
|
||||
select_mode = context.scene.tool_settings.gpencil_selectmode_edit
|
||||
matrix_world = ob.matrix_world.copy()
|
||||
|
||||
layers = [l for l in gp.layers if not l.hide and not l.lock]
|
||||
|
||||
region = context.region
|
||||
region_3d = context.space_data.region_3d
|
||||
|
||||
## TODO for frames, handle multiframe editing
|
||||
|
||||
avoid_ct = 0
|
||||
for layer in layers:
|
||||
for frame in layer.frames:
|
||||
drawing = frame.drawing
|
||||
|
||||
stroke_indices_to_delete = []
|
||||
## For stroke mode
|
||||
# stroke_indices_to_delete = [sidx for sidx, stroke in enumerate(drawing.strokes) if stroke.select and is_stroke_in_view(stroke, matrix_world, region, region_3d)]
|
||||
for sid, stroke in enumerate(drawing.strokes):
|
||||
if not stroke.select:
|
||||
continue
|
||||
|
||||
# Check if the stroke is within the view bounds
|
||||
if not is_stroke_in_view(stroke, matrix_world, region, region_3d):
|
||||
avoid_ct += 1
|
||||
continue
|
||||
|
||||
## No need for further check if we are in stroke mod (direct delete)
|
||||
if select_mode == 'STROKE':
|
||||
stroke_indices_to_delete.append(sid)
|
||||
continue
|
||||
|
||||
## --- Handle points ---
|
||||
|
||||
## Dissolve mode remove points (only remove by an amount from the end . need to rebuild the stroke !)
|
||||
select_count = len([p for p in stroke.points if p.select])
|
||||
if select_count == len(stroke.points):
|
||||
## mark as full delete and go next
|
||||
stroke_indices_to_delete.append(sid)
|
||||
continue
|
||||
|
||||
|
||||
## Make a copy of deselected points attributes
|
||||
point_attrs = []
|
||||
for p in stroke.points:
|
||||
if p.select:
|
||||
continue
|
||||
point_attrs.append([p.position.copy(), p.rotation, p.radius, p.opacity])
|
||||
|
||||
## remove as many points as select_count
|
||||
stroke.remove_points(select_count)
|
||||
|
||||
## re-assign attributes in order
|
||||
for i, p in enumerate(stroke.points):
|
||||
if i < len(point_attrs):
|
||||
p.position = point_attrs[i][0]
|
||||
p.rotation = point_attrs[i][1]
|
||||
p.radius = point_attrs[i][2]
|
||||
p.opacity = point_attrs[i][3]
|
||||
p.select = False # Deselect all points after processing
|
||||
|
||||
if stroke_indices_to_delete:
|
||||
# print(f'layer {layer.name} : delete {len(stroke_indices_to_delete)} strokes')
|
||||
drawing.remove_strokes(indices=stroke_indices_to_delete)
|
||||
|
||||
if avoid_ct:
|
||||
self.report({'WARNING'}, f"Skipped {avoid_ct} out of view")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def draw_delete_view_bound_ui(self, context):
|
||||
layout = self.layout
|
||||
layout.operator('grease_pencil.delete_view_bound', text='Delete View bound', icon='LOCKVIEW_ON') # RESTRICT_VIEW_ON
|
||||
|
||||
|
||||
classes = (
|
||||
GPT_OT_delete_strokes_view_bound,
|
||||
GPT_OT_delete_points_view_bound,
|
||||
# GP_OT_delete_strokes_view_bound,
|
||||
# GP_OT_delete_points_view_bound,
|
||||
GP_OT_delete_view_bound,
|
||||
)
|
||||
|
||||
def register():
|
||||
@ -172,6 +268,7 @@ def register():
|
||||
|
||||
for cl in classes:
|
||||
bpy.utils.register_class(cl)
|
||||
bpy.types.VIEW3D_MT_edit_greasepencil_delete.append(draw_delete_view_bound_ui)
|
||||
|
||||
## make scene property for empty key preservation and bake movement for layers...
|
||||
# register_keymaps()
|
||||
@ -180,6 +277,7 @@ def unregister():
|
||||
if bpy.app.background:
|
||||
return
|
||||
|
||||
bpy.types.VIEW3D_MT_edit_greasepencil_delete.remove(draw_delete_view_bound_ui)
|
||||
# unregister_keymaps()
|
||||
for cl in reversed(classes):
|
||||
bpy.utils.unregister_class(cl)
|
||||
|
Loading…
x
Reference in New Issue
Block a user