add intermediate stroke container - strokes to drawing.strokes

master
pullusb 2024-11-11 17:48:11 +01:00
parent 4732110b93
commit 1dfb8cff9c
13 changed files with 56 additions and 56 deletions

View File

@ -53,7 +53,7 @@ def create_gap_stroke(f, ob, tol=10, mat_id=None):
encounter = defaultdict(list)
plist = []
matrix = ob.matrix_world
for s in f.strokes: #add first and last
for s in f.drawing.strokes: #add first and last
smat = ob.material_slots[s.material_index].material
if not smat:
continue #no material on line
@ -219,8 +219,8 @@ def extend_all_strokes_tips(ob, frame, length=10, selected=False):
ct = 0
#TODO need to delete previous closing lines on frame before launching
# iterate in a copy of stroke list to avoid growing frame.strokes as we loop in !
for s in list(frame.strokes):
# iterate in a copy of stroke list to avoid growing frame.drawing.strokes as we loop in !
for s in list(frame.drawing.strokes):
if s.material_index == mat_id:#is a closeline
continue
if len(s.points) < 2:#not enough point to evaluate
@ -348,7 +348,7 @@ class GPSTK_OT_change_closeline_length(bpy.types.Operator):
if not l.current_frame():
print(f'{l.name} has no active frame')
continue
fct += change_extension_length(ob, [s for s in l.current_frame().strokes], length = self.length, selected = self.selected)
fct += change_extension_length(ob, [s for s in l.current_frame().drawing.strokes], length = self.length, selected = self.selected)
if not fct:
mess = "No extension modified... see console"
@ -378,7 +378,7 @@ class GPSTK_OT_comma_finder(bpy.types.Operator):
lays = [l for l in ob.data.layers if not l.hide and not l.lock]
for l in lays:
if not l.current_frame():continue
for s in l.current_frame().strokes:
for s in l.current_frame().drawing.strokes:
if is_deviating_by(s, context.scene.gpcolor_props.deviation_tolerance):
ct+=1

View File

@ -175,7 +175,7 @@ def copycut_strokes(layers=None, copy=True, keep_empty=True):
if not copy:
staylist = [] # init part of strokes that must survive on this layer
for s in f.strokes:
for s in f.drawing.strokes:
if s.select:
# separate in multiple stroke if parts of the strokes a selected.
sel = [i for i, p in enumerate(s.points) if p.select]
@ -192,7 +192,7 @@ def copycut_strokes(layers=None, copy=True, keep_empty=True):
if not copy:
maxindex = len(s.points)-1
if len(substrokes) == maxindex+1: # if only one substroke, then it's the full stroke
f.strokes.remove(s)
f.drawing.strokes.remove(s)
else:
neg = [i for i, p in enumerate(s.points) if not p.select]
@ -217,14 +217,14 @@ def copycut_strokes(layers=None, copy=True, keep_empty=True):
stroke_list.append(dump_gp_stroke(s,l))
#delete stroke on the fly
if not copy:
f.strokes.remove(s)
f.drawing.strokes.remove(s)
'''
if not copy:
# delete all selected strokes...
for s in f.strokes:
for s in f.drawing.strokes:
if s.select:
f.strokes.remove(s)
f.drawing.strokes.remove(s)
# ...recreate these uncutted ones
#pprint(staylist)
if staylist:
@ -234,7 +234,7 @@ def copycut_strokes(layers=None, copy=True, keep_empty=True):
#if nothing left on the frame choose to leave an empty frame or delete it (let previous frame appear)
if not copy and not keep_empty:#
if not len(f.strokes):
if not len(f.drawing.strokes):
l.frames.remove(f)
@ -273,7 +273,7 @@ def copy_all_strokes(layers=None):
if not f:
continue# active frame can be None
for s in f.strokes:
for s in f.drawing.strokes:
## full stroke version
# if s.select:
stroke_list.append(dump_gp_stroke_range(s, None, l, obj))
@ -313,7 +313,7 @@ def copy_all_strokes_in_frame(frame=None, layers=None, obj=None,
if not f:
continue# active frame can be None
for s in f.strokes:
for s in f.drawing.strokes:
## full stroke version
# if s.select:
# send index of all points to get the whole stroke with "range"
@ -326,7 +326,7 @@ def copy_all_strokes_in_frame(frame=None, layers=None, obj=None,
def add_stroke(s, frame, layer, obj, select=False):
'''add stroke on a given frame, (layer is for parentage setting)'''
# print(3*'-',s)
ns = frame.strokes.new()
ns = frame.drawing.strokes.new()
for att, val in s.items():
if att not in ('points'):
@ -566,7 +566,7 @@ class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
frame_dic = {}
for f in l.frames:
if skip_empty_frame and not len(f.strokes):
if skip_empty_frame and not len(f.drawing.strokes):
continue
context.scene.frame_set(f.frame_number) # use matrix of this frame
strokelist = copy_all_strokes_in_frame(frame=f, layers=l, obj=obj,
@ -603,7 +603,7 @@ class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
break
## skip empty frame if specified
if skip_empty_frame and not len(f.strokes):
if skip_empty_frame and not len(f.drawing.strokes):
continue
strokelist = copy_all_strokes_in_frame(frame=f, layers=l, obj=obj,

View File

@ -252,8 +252,8 @@ class GPTB_OT_eraser(Operator):
#print(self.cuts_data)
# for f in self.gp_frames:
# for s in [s for s in f.strokes if s.material_index==self.hld_index]:
# f.strokes.remove(s)
# for s in [s for s in f.drawing.strokes if s.material_index==self.hld_index]:
# f.drawing.strokes.remove(s)
#gp.data.materials.pop(index=self.hld_index)
#bpy.data.materials.remove(self.hld_mat)
@ -281,7 +281,7 @@ class GPTB_OT_eraser(Operator):
bpy.ops.gpencil.select_all(action='DESELECT')
bpy.ops.gpencil.select_circle(x=x, y=y, radius=radius, wait_for_input=False)
strokes = [s for f in self.gp_frames for s in f.strokes]
strokes = [s for f in self.gp_frames for s in f.drawing.strokes]
#print('select_circle', time()-t1)
t2 = time()
@ -329,7 +329,7 @@ class GPTB_OT_eraser(Operator):
bpy.ops.gpencil.select_circle(x=x, y=y, radius=radius, wait_for_input=False)
'''
selected_strokes = [s for f in self.gp_frames for s in f.strokes if s.select]
selected_strokes = [s for f in self.gp_frames for s in f.drawing.strokes if s.select]
tip_points = [p for s in selected_strokes for i, p in enumerate(s.points) if p.select and (i==0 or i == len(s.points)-1)]
bpy.ops.gpencil.select_less()
@ -341,7 +341,7 @@ class GPTB_OT_eraser(Operator):
'''
t4 = time()
selected_strokes = [s for f in self.gp_frames for s in f.strokes if s.select]
selected_strokes = [s for f in self.gp_frames for s in f.drawing.strokes if s.select]
if selected_strokes:
bpy.ops.gpencil.delete(type='POINTS')
@ -359,7 +359,7 @@ class GPTB_OT_eraser(Operator):
#bpy.ops.object.mode_set(mode='OBJECT')
context.scene.tool_settings.gpencil_selectmode_edit = self.gpencil_selectmode_edit
bpy.ops.object.mode_set(mode='PAINT_GREASE_PENCIL')
#selected_strokes = [s for s in self.gp_frame.strokes if s.select]
#selected_strokes = [s for s in self.gp_frame.drawing.strokes if s.select]
#bpy.ops.object.mode_set(mode='PAINT_GREASE_PENCIL')
def modal(self, context, event):
@ -443,7 +443,7 @@ class GPTB_OT_eraser(Operator):
gp_layers = [l for l in gp.data.layers if not l.lock or l.hide]
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.strokes]
points_data = [(s, f, gp_mats[s.material_index]) for f in gp_frames for s in f.drawing.strokes]
points_data = [(s, f, m) for s, f, m in points_data if not m.grease_pencil.hide or m.grease_pencil.lock]
print('get_gp_points', time()-t0)
@ -481,7 +481,7 @@ class GPTB_OT_eraser(Operator):
self.hld_strokes = []
for f in self.gp_frames:
hld_stroke = f.strokes.new()
hld_stroke = f.drawing.strokes.new()
hld_stroke.start_cap_mode = 'ROUND'
hld_stroke.end_cap_mode = 'ROUND'
hld_stroke.material_index = self.hld_index

View File

@ -16,7 +16,7 @@ def remove_stroke_exact_duplications(apply=True):
for l in gp.layers:
for f in l.frames:
stroke_list = []
for s in reversed(f.strokes):
for s in reversed(f.drawing.strokes):
point_list = [p.position for p in s.points]
@ -24,7 +24,7 @@ def remove_stroke_exact_duplications(apply=True):
ct += 1
if apply:
# Remove redundancy
f.strokes.remove(s)
f.drawing.strokes.remove(s)
else:
stroke_list.append(point_list)
return ct

View File

@ -19,7 +19,7 @@ def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=
oframe = bpy.context.scene.frame_current
omode = bpy.context.mode
# frame_list = [ f.frame_number for l in obj.data.layers for f in l.frames if len(f.strokes)]
# frame_list = [ f.frame_number for l in obj.data.layers for f in l.frames if len(f.drawing.strokes)]
# frame_list = list(set(frame_list))
# frame_list.sort()
# for fnum in frame_list:
@ -38,7 +38,7 @@ def batch_flat_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=
bpy.context.scene.camera.location = bpy.context.scene.camera.location
scn.frame_current = f.frame_number
for s in f.strokes:
for s in f.drawing.strokes:
for p in s.points:
p.position = obj.matrix_world.inverted() @ region_to_location(location_to_region(obj.matrix_world @ p.position), scn.cursor.location)
@ -67,7 +67,7 @@ def batch_flat_reproject(obj):
plane_no.rotate(cam_mat)
plane_co = scn.cursor.location
for s in f.strokes:
for s in f.drawing.strokes:
points_co = [obj.matrix_world @ p.position for p in s.points]
points_co = [mat_inv @ intersect_line_plane(origin, p, plane_co, plane_no) for p in points_co]
points_co = [co for vector in points_co for co in vector]
@ -102,7 +102,7 @@ def batch_flat_reproject(obj):
if f.frame_number != scn.frame_current:
f = l.frames.copy(f) # duplicate content of the previous frame
for s in f.strokes:
for s in f.drawing.strokes:
points_co = [obj.matrix_world @ p.position for p in s.points]
points_co = [mat_inv @ intersect_line_plane(origin, p, plane_co, plane_no) for p in points_co]
points_co = [co for vector in points_co for co in vector]

View File

@ -624,13 +624,13 @@ class GPTB_OT_clear_active_frame(Operator):
self.report({'ERROR'}, 'No active frame')
return {'CANCELLED'}
ct = len(f.strokes)
ct = len(f.drawing.strokes)
if not ct:
self.report({'ERROR'}, 'Active frame already empty')
return {'CANCELLED'}
for s in reversed(f.strokes):
f.strokes.remove(s)
for s in reversed(f.drawing.strokes):
f.drawing.strokes.remove(s)
self.report({'INFO'}, f'Cleared active frame ({ct} strokes removed)')
return {'FINISHED'}

View File

@ -81,7 +81,7 @@ class GP_OT_pick_closest_layer(Operator):
for f in l.frames:
if not f.select:
continue
for s in f.strokes:
for s in f.drawing.strokes:
if self.stroke_filter == 'STROKE' and not self.ob.data.materials[s.material_index].grease_pencil.show_stroke:
continue
elif self.stroke_filter == 'FILL' and not self.ob.data.materials[s.material_index].grease_pencil.show_fill:
@ -93,7 +93,7 @@ class GP_OT_pick_closest_layer(Operator):
for layer_id, l in enumerate(gp.layers):
if l.hide or not l.current_frame(): # l.lock or
continue
for s in l.current_frame().strokes:
for s in l.current_frame().drawing.strokes:
if self.stroke_filter == 'STROKE' and not self.ob.data.materials[s.material_index].grease_pencil.show_stroke:
continue
elif self.stroke_filter == 'FILL' and not self.ob.data.materials[s.material_index].grease_pencil.show_fill:

View File

@ -116,7 +116,7 @@ class GPTB_OT_move_material_to_layer(Operator) :
continue
for f in l.frames:
## skip if no stroke has active material
if not next((s for s in f.strokes if s.material_index == mat_index), None):
if not next((s for s in f.drawing.strokes if s.material_index == mat_index), None):
continue
## Get/Create a destination frame and keep a reference to it
if not (dest_key := key_dict.get(f.frame_number)):
@ -126,7 +126,7 @@ class GPTB_OT_move_material_to_layer(Operator) :
print(f'{ob.name} : frame {f.frame_number}')
## Replicate strokes in dest_keys
stroke_to_delete = []
for s in f.strokes:
for s in f.drawing.strokes:
if s.material_index == mat_index:
utils.copy_stroke_to_frame(s, dest_key)
stroke_to_delete.append(s)
@ -142,7 +142,7 @@ class GPTB_OT_move_material_to_layer(Operator) :
## Remove from source frame (f)
if not self.copy:
for s in reversed(stroke_to_delete):
f.strokes.remove(s)
f.drawing.strokes.remove(s)
## ? Remove frame if layer is empty ? -> probably not, will show previous frame

View File

@ -84,7 +84,7 @@ class GP_OT_pick_closest_material(Operator):
for f in l.frames:
if not f.select:
continue
for s in f.strokes:
for s in f.drawing.strokes:
self.stroke_list.append(s)
else:
@ -92,7 +92,7 @@ class GP_OT_pick_closest_material(Operator):
for l in self.gp.layers:
if l.hide or not l.current_frame():# l.lock or
continue
for s in l.current_frame().strokes:
for s in l.current_frame().drawing.strokes:
self.stroke_list.append(s)
if self.fill_only:
@ -240,7 +240,7 @@ class GP_OT_pick_closest_material(Operator):
for f in l.frames:
if not f.select:
continue
for s in f.strokes:
for s in f.drawing.strokes:
self.stroke_list.append(s)
else:
@ -248,7 +248,7 @@ class GP_OT_pick_closest_material(Operator):
for l in gp.layers:
if l.hide or not l.current_frame():# l.lock or
continue
for s in l.current_frame().strokes:
for s in l.current_frame().drawing.strokes:
self.stroke_list.append(s)
if self.stroke_filter == 'FILL':

View File

@ -410,7 +410,7 @@ class GPTB_OT_clean_material_stack(bpy.types.Operator):
# iterate in all strokes and replace with new_mat_id
for l in ob.data.layers:
for f in l.frames:
for s in f.strokes:
for s in f.drawing.strokes:
if s.material_index == i:
s.material_index = new_mat_id
@ -427,7 +427,7 @@ class GPTB_OT_clean_material_stack(bpy.types.Operator):
# if self.skip_binded_empty_slots:
# for l in ob.data.layers:
# for f in l.frames:
# for s in f.strokes:
# for s in f.drawing.strokes:
# if s.material_index == i:
# is_binded = True
# break

View File

@ -54,7 +54,7 @@ def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False
plan_co, plane_no = utils.get_gp_draw_plane(obj, orient=proj_type)
frame_list = [f.frame_number for l in obj.data.layers for f in l.frames if len(f.strokes)]
frame_list = [f.frame_number for l in obj.data.layers for f in l.frames if len(f.drawing.strokes)]
frame_list = list(set(frame_list))
frame_list.sort()
@ -78,7 +78,7 @@ def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False
f = next((f for f in l.frames if f.frame_number == i), None)
if f is None:
continue
for s in f.strokes:
for s in f.drawing.strokes:
## Batch matrix apply (Here is slower than list comprehension).
# nb_points = len(s.points)
# coords = np.empty(nb_points * 3, dtype='float64')
@ -139,7 +139,7 @@ def align_global(reproject=True, ref=None, all_strokes=True):
# world_coords = []
for l in o.data.layers:
for f in l.frames:
for s in f.strokes:
for s in f.drawing.strokes:
## foreach
coords = [p.position @ mat.inverted() @ new_mat for p in s.points]
# print('coords: ', coords)
@ -216,7 +216,7 @@ def align_all_frames(reproject=True, ref=None, all_strokes=True):
scale_mat = get_scale_matrix(o_scale)
new_mat = loc_mat @ rot_mat @ scale_mat
for s in f.strokes:
for s in f.drawing.strokes:
## foreach
coords = [p.position @ mat.inverted() @ new_mat for p in s.points]
# print('coords: ', coords)

View File

@ -99,7 +99,7 @@ def gp_stroke_angle_split (frame, strokes, angle):
splitted_loops = bm_angle_split(bm,angle)
frame.strokes.remove(stroke_info['stroke'])
frame.drawing.strokes.remove(stroke_info['stroke'])
for loop in splitted_loops :
loop_info = [{'co':v.co,'strength': v[strength], 'pressure' :v[pressure],'select':v[select]} for v in loop]
new_stroke = draw_gp_stroke(loop_info,frame,palette,width = line_width)

View File

@ -29,7 +29,7 @@ def get_matrix(ob) :
return ob.matrix_world.copy()
def set_matrix(gp_frame,mat):
for stroke in gp_frame.strokes :
for stroke in gp_frame.drawing.strokes :
for point in stroke.points :
point.position = mat @ point.position
@ -160,7 +160,7 @@ def simple_draw_gp_stroke(pts, frame, width = 2, mat_id = 0):
draw basic stroke by passing list of point 3D coordinate
the frame to draw on and optional width parameter (default = 2)
'''
stroke = frame.strokes.new()
stroke = frame.drawing.strokes.new()
stroke.line_width = width
stroke.display_mode = '3DSPACE'
stroke.material_index = mat_id
@ -178,7 +178,7 @@ def simple_draw_gp_stroke(pts, frame, width = 2, mat_id = 0):
## OLD - need update
def draw_gp_stroke(loop_info, frame, palette, width = 2) :
stroke = frame.strokes.new(palette)
stroke = frame.drawing.strokes.new(palette)
stroke.line_width = width
stroke.display_mode = '3DSPACE'# old -> draw_mode
@ -472,14 +472,14 @@ def get_stroke_2D_coords(stroke):
def get_all_stroke_2D_coords(frame):
'''return a list of lists with all strokes's points 2D location'''
## using modification from get_stroke_2D_coords func'
return [get_stroke_2D_coords(s) for s in frame.strokes]
return [get_stroke_2D_coords(s) for s in frame.drawing.strokes]
## direct
#return[[location_to_region(p.position) for p in s.points] for s in frame.strokes]
#return[[location_to_region(p.position) for p in s.points] for s in frame.drawing.strokes]
def selected_strokes(frame):
'''return all stroke having a point selected as a list of strokes objects'''
stlist = []
for i, s in enumerate(frame.strokes):
for i, s in enumerate(frame.drawing.strokes):
if any(pt.select for pt in s.points):
stlist.append(s)
return stlist
@ -491,7 +491,7 @@ def copy_stroke_to_frame(s, frame, select=True):
return created stroke
'''
ns = frame.strokes.new()
ns = frame.drawing.strokes.new()
## Set strokes attr
stroke_attr = [