Respect group lock and hide state

master
pullusb 2024-12-16 17:29:27 +01:00
parent 1c39d81ef1
commit cf3f39b730
12 changed files with 47 additions and 63 deletions

View File

@ -6,6 +6,7 @@ from bpy.props import (FloatProperty,
StringProperty, StringProperty,
IntProperty) IntProperty)
from .. import utils from .. import utils
from ..utils import is_hidden
## copied from OP_key_duplicate_send ## copied from OP_key_duplicate_send
def get_layer_list(self, context): def get_layer_list(self, context):
@ -142,7 +143,7 @@ class GP_OT_create_empty_frames(bpy.types.Operator):
tgt_layers = [l for i, l in enumerate(gpl) if i == active_index - 1] tgt_layers = [l for i, l in enumerate(gpl) if i == active_index - 1]
elif self.targeted_layers == 'ALL_VISIBLE': elif self.targeted_layers == 'ALL_VISIBLE':
tgt_layers = [l for l in gpl if not l.hide and l != gpl.active] tgt_layers = [l for l in gpl if not is_hidden(l) and l != gpl.active]
elif self.targeted_layers == 'CHOSEN': elif self.targeted_layers == 'CHOSEN':
if not self.layers_enum: if not self.layers_enum:
@ -220,4 +221,4 @@ def register():
bpy.utils.register_class(GP_OT_create_empty_frames) bpy.utils.register_class(GP_OT_create_empty_frames)
def unregister(): def unregister():
bpy.utils.unregister_class(GP_OT_create_empty_frames) bpy.utils.unregister_class(GP_OT_create_empty_frames)

View File

@ -5,11 +5,14 @@ from ..utils import (location_to_region,
vector_length, vector_length,
draw_gp_stroke, draw_gp_stroke,
extrapolate_points_by_length, extrapolate_points_by_length,
simple_draw_gp_stroke) simple_draw_gp_stroke,
is_hidden,
is_locked)
import bpy import bpy
from math import degrees from math import degrees
from mathutils import Vector from mathutils import Vector
# from os.path import join, basename, exists, dirname, abspath, splitext # from os.path import join, basename, exists, dirname, abspath, splitext
# iterate over selected layer and all/selected frame and close gaps between line extermities with a tolerance level # iterate over selected layer and all/selected frame and close gaps between line extermities with a tolerance level
@ -276,9 +279,9 @@ class GPSTK_OT_extend_lines(bpy.types.Operator):
if self.layer_tgt == 'ACTIVE': if self.layer_tgt == 'ACTIVE':
lays = [ob.data.layers.active] lays = [ob.data.layers.active]
elif self.layer_tgt == 'SELECTED': elif self.layer_tgt == 'SELECTED':
lays = [l for l in ob.data.layers if l.select and not l.hide] lays = [l for l in ob.data.layers if l.select and not is_hidden(l)]
elif self.layer_tgt == 'ALL_VISIBLE': elif self.layer_tgt == 'ALL_VISIBLE':
lays = [l for l in ob.data.layers if not l.hide] lays = [l for l in ob.data.layers if not is_hidden(l)]
else: else:
lays = [l for l in ob.data.layers if not any(x in l.name for x in ('spot', 'colo'))] lays = [l for l in ob.data.layers if not any(x in l.name for x in ('spot', 'colo'))]
@ -337,9 +340,9 @@ class GPSTK_OT_change_closeline_length(bpy.types.Operator):
if self.layer_tgt == 'ACTIVE': if self.layer_tgt == 'ACTIVE':
lays = [ob.data.layers.active] lays = [ob.data.layers.active]
elif self.layer_tgt == 'SELECTED': elif self.layer_tgt == 'SELECTED':
lays = [l for l in ob.data.layers if l.select and not l.hide] lays = [l for l in ob.data.layers if l.select and not is_hidden(l)]
elif self.layer_tgt == 'ALL_VISIBLE': elif self.layer_tgt == 'ALL_VISIBLE':
lays = [l for l in ob.data.layers if not l.hide] lays = [l for l in ob.data.layers if not is_hidden(l)]
else: else:
lays = [l for l in ob.data.layers if not any(x in l.name for x in ('spot', 'colo'))] lays = [l for l in ob.data.layers if not any(x in l.name for x in ('spot', 'colo'))]
@ -375,7 +378,7 @@ class GPSTK_OT_comma_finder(bpy.types.Operator):
def execute(self, context): def execute(self, context):
ct = 0 ct = 0
ob = context.object ob = context.object
lays = [l for l in ob.data.layers if not l.hide and not l.lock] lays = [l for l in ob.data.layers if not is_hidden(l) and not is_locked(l)]
for l in lays: for l in lays:
if not l.current_frame():continue if not l.current_frame():continue
for s in l.current_frame().drawing.strokes: for s in l.current_frame().drawing.strokes:

View File

@ -9,6 +9,7 @@ import json
from time import time from time import time
from operator import itemgetter from operator import itemgetter
from itertools import groupby from itertools import groupby
from .utils import is_locked, is_hidden
def convertAttr(Attr): def convertAttr(Attr):
'''Convert given value to a Json serializable format''' '''Convert given value to a Json serializable format'''
@ -139,7 +140,7 @@ def copycut_strokes(layers=None, copy=True, keep_empty=True):
# color = gp.palettes.active.colors.active.name # color = gp.palettes.active.colors.active.name
if not layers: if not layers:
# by default all visible layers # by default all visible layers
layers = [l for l in gpl if not l.hide and not l.lock] # [] layers = [l for l in gpl if not is_hidden(l) and not is_locked(l)] # []
if not isinstance(layers, list): if not isinstance(layers, list):
# if a single layer object is send put in a list # if a single layer object is send put in a list
layers = [layers] layers = [layers]
@ -235,7 +236,7 @@ def copy_all_strokes(layers=None):
if not layers: if not layers:
# by default all visible layers # by default all visible layers
layers = [l for l in gpl if not l.hide and not l.lock]# include locked ? layers = [l for l in gpl if not is_hidden(l) and not is_locked(l)]# include locked ?
if not isinstance(layers, list): if not isinstance(layers, list):
# if a single layer object is send put in a list # if a single layer object is send put in a list
layers = [layers] layers = [layers]
@ -275,7 +276,7 @@ def copy_all_strokes_in_frame(frame=None, layers=None, obj=None,
if not layers: if not layers:
# by default all visible layers # by default all visible layers
layers = [l for l in gpl if not l.hide and not l.lock] # include locked ? layers = [l for l in gpl if not is_hidden(l) and not is_locked(l)] # include locked ?
if not isinstance(layers, list): if not isinstance(layers, list):
# if a single layer object is send put in a list # if a single layer object is send put in a list
layers = [layers] layers = [layers]
@ -521,7 +522,7 @@ class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
#ct = check_radius() #ct = check_radius()
layerdic = {} layerdic = {}
layerpool = [l for l in gpl if not l.hide and l.select] # and not l.lock layerpool = [l for l in gpl if not is_hidden(l) and l.select] # and not is_locked(l)
if not layerpool: if not layerpool:
self.report({'ERROR'}, 'No layers selected in GP dopesheet (needs to be visible and selected to be copied)\nHint: Changing active layer reset selection to active only') self.report({'ERROR'}, 'No layers selected in GP dopesheet (needs to be visible and selected to be copied)\nHint: Changing active layer reset selection to active only')
return {"CANCELLED"} return {"CANCELLED"}

View File

@ -11,6 +11,7 @@ from bpy_extras.view3d_utils import region_2d_to_location_3d, region_2d_to_vecto
location_3d_to_region_2d, region_2d_to_origin_3d, region_2d_to_location_3d location_3d_to_region_2d, region_2d_to_origin_3d, region_2d_to_location_3d
from time import time from time import time
from math import pi, cos, sin from math import pi, cos, sin
from .utils import is_locked, is_hidden
def get_gp_mat(gp, name, set_active=False): def get_gp_mat(gp, name, set_active=False):
@ -440,7 +441,7 @@ class GPTB_OT_eraser(Operator):
t0 = time() t0 = time()
gp_mats = gp.data.materials gp_mats = gp.data.materials
gp_layers = [l for l in gp.data.layers if not l.lock or l.hide] gp_layers = [l for l in gp.data.layers if not is_locked(l) or is_hidden(l)]
self.gp_frames = [l.current_frame() for l in gp_layers] self.gp_frames = [l.current_frame() for l in gp_layers]
''' '''
points_data = [(s, f, gp_mats[s.material_index]) for f in gp_frames for s in f.drawing.strokes] points_data = [(s, f, gp_mats[s.material_index]) for f in gp_frames for s in f.drawing.strokes]

View File

@ -2,6 +2,7 @@ import bpy
import os import os
from pathlib import Path from pathlib import Path
import numpy as np import numpy as np
from . import utils from . import utils
from bpy.props import (BoolProperty, from bpy.props import (BoolProperty,

View File

@ -12,7 +12,7 @@ from .utils import (location_to_region, region_to_location)
## Do not work on multiple object ## Do not work on multiple object
def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False): def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
'''Reproject '''Reproject
:all_stroke: affect hided, locked layers :all_stroke: affect hidden, locked layers
''' '''
if restore_frame: if restore_frame:

View File

@ -2,7 +2,6 @@ import bpy
from mathutils import Vector from mathutils import Vector
from . import utils from . import utils
class GPTB_OT_create_follow_path_curve(bpy.types.Operator): class GPTB_OT_create_follow_path_curve(bpy.types.Operator):
bl_idname = "object.create_follow_path_curve" bl_idname = "object.create_follow_path_curve"
bl_label = "Create Follow Path Curve" bl_label = "Create Follow Path Curve"

View File

@ -1,5 +1,5 @@
import bpy import bpy
from .utils import get_addon_prefs from .utils import get_addon_prefs, is_locked, is_hidden
from bpy.props import BoolProperty ,EnumProperty ,StringProperty from bpy.props import BoolProperty ,EnumProperty ,StringProperty
class GPTB_OT_jump_gp_keyframe(bpy.types.Operator): class GPTB_OT_jump_gp_keyframe(bpy.types.Operator):
@ -45,15 +45,15 @@ class GPTB_OT_jump_gp_keyframe(bpy.types.Operator):
return {"CANCELLED"} return {"CANCELLED"}
if self.target == 'ACTIVE': if self.target == 'ACTIVE':
gpl = [l for l in context.object.data.layers if l.select and not l.hide] gpl = [l for l in context.object.data.layers if l.select and not is_hidden(l)]
if not context.object.data.layers.active in gpl: if not context.object.data.layers.active in gpl:
gpl.append(context.object.data.layers.active) gpl.append(context.object.data.layers.active)
elif self.target == 'VISIBLE': elif self.target == 'VISIBLE':
gpl = [l for l in context.object.data.layers if not l.hide] gpl = [l for l in context.object.data.layers if not is_hidden(l)]
elif self.target == 'ACCESSIBLE': elif self.target == 'ACCESSIBLE':
gpl = [l for l in context.object.data.layers if not l.hide and not l.lock] gpl = [l for l in context.object.data.layers if not is_hidden(l) and not is_locked(l)]
if self.keyframe_type != 'NONE': if self.keyframe_type != 'NONE':
# use shortcut choice override # use shortcut choice override

View File

@ -4,7 +4,7 @@ import mathutils
from mathutils import Vector, Matrix, geometry from mathutils import Vector, Matrix, geometry
from bpy_extras import view3d_utils from bpy_extras import view3d_utils
from time import time from time import time
from .utils import get_gp_draw_plane, location_to_region, region_to_location from .utils import get_gp_draw_plane, location_to_region, region_to_location, is_locked, is_hidden
class GP_OT_pick_closest_layer(Operator): class GP_OT_pick_closest_layer(Operator):
bl_idname = "gp.pick_closest_layer" bl_idname = "gp.pick_closest_layer"
@ -76,7 +76,7 @@ class GP_OT_pick_closest_layer(Operator):
self.point_pair = [] self.point_pair = []
if context.scene.tool_settings.use_grease_pencil_multi_frame_editing: if context.scene.tool_settings.use_grease_pencil_multi_frame_editing:
for layer in gp.layers: for layer in gp.layers:
if layer.hide: if is_hidden(layer):
continue continue
for f in layer.frames: for f in layer.frames:
if not f.select: if not f.select:
@ -89,9 +89,9 @@ class GP_OT_pick_closest_layer(Operator):
self.point_pair += [(Vector((*location_to_region(mat @ p.position), 0)), layer) for p in s.points] self.point_pair += [(Vector((*location_to_region(mat @ p.position), 0)), layer) for p in s.points]
else: else:
# [s for l in gp.layers if not l.lock and not l.hide for s in l.current_frame().stokes] # [s for l in gp.layers if not is_locked(l) and not is_hidden(l) for s in l.current_frame().stokes]
for layer in gp.layers: for layer in gp.layers:
if layer.hide or not layer.current_frame(): if is_hidden(layer) or not layer.current_frame():
continue continue
for s in layer.current_frame().drawing.strokes: for s in layer.current_frame().drawing.strokes:
if self.stroke_filter == 'STROKE' and not self.ob.data.materials[s.material_index].grease_pencil.show_stroke: if self.stroke_filter == 'STROKE' and not self.ob.data.materials[s.material_index].grease_pencil.show_stroke:

View File

@ -4,7 +4,12 @@ import mathutils
from mathutils import Vector, Matrix, geometry from mathutils import Vector, Matrix, geometry
from bpy_extras import view3d_utils from bpy_extras import view3d_utils
from time import time from time import time
from .utils import get_gp_draw_plane, location_to_region, region_to_location from .utils import (get_gp_draw_plane,
location_to_region,
region_to_location,
is_locked,
is_hidden)
### passing by 2D projection ### passing by 2D projection
def get_3d_coord_on_drawing_plane_from_2d(context, co): def get_3d_coord_on_drawing_plane_from_2d(context, co):
@ -79,7 +84,7 @@ class GP_OT_pick_closest_material(Operator):
if context.scene.tool_settings.use_grease_pencil_multi_frame_editing: if context.scene.tool_settings.use_grease_pencil_multi_frame_editing:
for l in self.gp.layers: for l in self.gp.layers:
if l.hide:# l.lock or if is_hidden(l):# is_locked(l) or
continue continue
for f in l.frames: for f in l.frames:
if not f.select: if not f.select:
@ -88,9 +93,9 @@ class GP_OT_pick_closest_material(Operator):
self.stroke_list.append(s) self.stroke_list.append(s)
else: else:
# [s for l in self.gp.layers if not l.lock and not l.hide for s in l.current_frame().stokes] # [s for l in self.gp.layers if not is_locked(l) and not is_hidden(l) for s in l.current_frame().stokes]
for l in self.gp.layers: for l in self.gp.layers:
if l.hide or not l.current_frame():# l.lock or if is_hidden(l) or not l.current_frame():# is_locked(l) or
continue continue
for s in l.current_frame().drawing.strokes: for s in l.current_frame().drawing.strokes:
self.stroke_list.append(s) self.stroke_list.append(s)
@ -235,7 +240,7 @@ class GP_OT_pick_closest_material(Operator):
if context.scene.tool_settings.use_grease_pencil_multi_frame_editing: if context.scene.tool_settings.use_grease_pencil_multi_frame_editing:
for l in gp.layers: for l in gp.layers:
if l.hide:# l.lock or if is_hidden(l):# is_locked(l) or
continue continue
for f in l.frames: for f in l.frames:
if not f.select: if not f.select:
@ -244,9 +249,9 @@ class GP_OT_pick_closest_material(Operator):
self.stroke_list.append(s) self.stroke_list.append(s)
else: else:
# [s for l in gp.layers if not l.lock and not l.hide for s in l.current_frame().stokes] # [s for l in gp.layers if not is_locked(l) and not is_hidden(l) for s in l.current_frame().stokes]
for l in gp.layers: for l in gp.layers:
if l.hide or not l.current_frame():# l.lock or if is_hidden(l) or not l.current_frame():# is_locked(l) or
continue continue
for s in l.current_frame().drawing.strokes: for s in l.current_frame().drawing.strokes:
self.stroke_list.append(s) self.stroke_list.append(s)

View File

@ -1,11 +1,13 @@
import bpy import bpy
import mathutils import mathutils
import numpy as np
from mathutils import Matrix, Vector from mathutils import Matrix, Vector
from math import pi from math import pi
import numpy as np
from time import time from time import time
from . import utils
from mathutils.geometry import intersect_line_plane from mathutils.geometry import intersect_line_plane
from . import utils
from .utils import is_hidden, is_locked
def get_scale_matrix(scale): def get_scale_matrix(scale):
# recreate a neutral mat scale # recreate a neutral mat scale
@ -15,35 +17,6 @@ def get_scale_matrix(scale):
matscale = matscale_x @ matscale_y @ matscale_z matscale = matscale_x @ matscale_y @ matscale_z
return matscale return matscale
'''
## Old reproject method using Operators:
omode = bpy.context.mode
if all_strokes:
layers_state = [[l, l.hide, l.lock, l.lock_frame] for l in obj.data.layers]
for l in obj.data.layers:
l.hide = False
l.lock = False
l.lock_frame = False
bpy.ops.object.mode_set(mode='EDIT')
for fnum in frame_list:
bpy.context.scene.frame_current = fnum
bpy.ops.gpencil.select_all(action='SELECT')
bpy.ops.gpencil.reproject(type=proj_type) # 'INVOKE_DEFAULT'
bpy.ops.gpencil.select_all(action='DESELECT')
# restore
if all_strokes:
for layer, hide, lock, lock_frame in layers_state:
layer.hide = hide
layer.lock = lock
layer.lock_frame = lock_frame
bpy.ops.object.mode_set(mode=omode)
'''
def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False): def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
'''Reproject - ops method '''Reproject - ops method
:all_stroke: affect hidden, locked layers :all_stroke: affect hidden, locked layers
@ -73,7 +46,7 @@ def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False
if not all_strokes: if not all_strokes:
if not layer.select: if not layer.select:
continue continue
if layer.hide or layer.lock: if is_hidden(layer) or is_locked(layer):
continue continue
frame = next((f for f in layer.frames if f.frame_number == i), None) frame = next((f for f in layer.frames if f.frame_number == i), None)

View File

@ -4,7 +4,7 @@ bl_info = {
"name": "GP toolbox", "name": "GP toolbox",
"description": "Tool set for Grease Pencil in animation production", "description": "Tool set for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux", "author": "Samuel Bernou, Christophe Seux",
"version": (4, 0, 3), "version": (4, 0, 4),
"blender": (4, 3, 0), "blender": (4, 3, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "", "warning": "",