added a 40s timeout on frame analisys
0.5.7 - added: timeout on scene plit and autocrop border to avoid freezing blender - ui: minor correctionmain
parent
64695a042f
commit
20ab99889d
|
@ -14,6 +14,11 @@ Activate / deactivate layer opaticty according to prefix
|
||||||
Activate / deactivate all masks using MA layers
|
Activate / deactivate all masks using MA layers
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
0.5.7
|
||||||
|
|
||||||
|
- added: timeout on scene plit and autocrop border to avoid freezing blender
|
||||||
|
- ui: minor correction
|
||||||
|
|
||||||
0.5.6
|
0.5.6
|
||||||
|
|
||||||
- feat: `check layers` new `clear frame out of range` option (Disabled by default)
|
- feat: `check layers` new `clear frame out of range` option (Disabled by default)
|
||||||
|
|
|
@ -93,7 +93,7 @@ class GPEXP_OT_add_objects_to_render(bpy.types.Operator):
|
||||||
class GPEXP_OT_split_to_scene(bpy.types.Operator):
|
class GPEXP_OT_split_to_scene(bpy.types.Operator):
|
||||||
bl_idname = "gp.split_to_scene"
|
bl_idname = "gp.split_to_scene"
|
||||||
bl_label = "Split Objects To Scene"
|
bl_label = "Split Objects To Scene"
|
||||||
bl_description = "Take selected objects and send them to separate scene"
|
bl_description = "Take selected objects and send them to separate scene\n(new scene is named after active object)"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -103,7 +103,10 @@ class GPEXP_OT_split_to_scene(bpy.types.Operator):
|
||||||
mode : bpy.props.StringProperty(default='ALL', options={'SKIP_SAVE'})
|
mode : bpy.props.StringProperty(default='ALL', options={'SKIP_SAVE'})
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
fn.split_object_to_scene()
|
err = fn.split_object_to_scene()
|
||||||
|
if err:
|
||||||
|
self.report({'ERROR'}, err)
|
||||||
|
return {"CANCELLED"}
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,11 @@ class GPEXP_OT_set_crop_from_selection(bpy.types.Operator):
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
scn = context.scene
|
scn = context.scene
|
||||||
fn.set_box_from_selected_objects(scn=scn, cam=scn.camera)
|
err = fn.set_box_from_selected_objects(scn=scn, cam=scn.camera)
|
||||||
|
if err:
|
||||||
|
self.report({'ERROR'}, err)
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
scn.render.use_border = True
|
scn.render.use_border = True
|
||||||
scn.render.use_crop_to_border = True
|
scn.render.use_crop_to_border = True
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
|
@ -2,7 +2,7 @@ bl_info = {
|
||||||
"name": "GP Render",
|
"name": "GP Render",
|
||||||
"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, 5, 6),
|
"version": (0, 5, 7),
|
||||||
"blender": (2, 93, 0),
|
"blender": (2, 93, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
22
fn.py
22
fn.py
|
@ -803,7 +803,10 @@ def export_crop_to_json():
|
||||||
return coord_dic
|
return coord_dic
|
||||||
|
|
||||||
def set_border_region_from_coord(coords, scn=None, margin=30, export_json=True):
|
def set_border_region_from_coord(coords, scn=None, margin=30, export_json=True):
|
||||||
'''Get a list of point coord in worldcamera view space (0 to 1) on each axis'''
|
'''Get a list of point coord in worldcamera view space (0 to 1) on each axis
|
||||||
|
set border (of passed scene :scn: ) with given coordinate
|
||||||
|
return the coords list as pixel coordinate
|
||||||
|
'''
|
||||||
|
|
||||||
scn = scn or bpy.context.scene
|
scn = scn or bpy.context.scene
|
||||||
|
|
||||||
|
@ -883,14 +886,16 @@ def has_anim(ob):
|
||||||
# TODO make a better check (check if there is only one key in each channel, count as not animated)
|
# TODO make a better check (check if there is only one key in each channel, count as not animated)
|
||||||
return ob.animation_data and ob.animation_data.action
|
return ob.animation_data and ob.animation_data.action
|
||||||
|
|
||||||
def get_gp_box_all_frame_selection(oblist=None, scn=None, cam=None):
|
def get_gp_box_all_frame_selection(oblist=None, scn=None, cam=None, timeout=40):
|
||||||
'''
|
'''
|
||||||
get points of all selection
|
get points of all selection
|
||||||
return 2d bbox in pixels
|
return 2d bbox in pixels
|
||||||
|
return None if timeout (too long to process, better to do it visually)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from bpy_extras.object_utils import world_to_camera_view
|
from bpy_extras.object_utils import world_to_camera_view
|
||||||
|
|
||||||
|
t0 = time()
|
||||||
coords_cam_list = []
|
coords_cam_list = []
|
||||||
scn = scn or bpy.context.scene
|
scn = scn or bpy.context.scene
|
||||||
oblist = oblist or [o for o in scn.objects if o.select_get()]
|
oblist = oblist or [o for o in scn.objects if o.select_get()]
|
||||||
|
@ -912,6 +917,10 @@ def get_gp_box_all_frame_selection(oblist=None, scn=None, cam=None):
|
||||||
if len(s.points) == 1: # skip isolated points
|
if len(s.points) == 1: # skip isolated points
|
||||||
continue
|
continue
|
||||||
coords_cam_list += [world_to_camera_view(scn, cam, ob.matrix_world @ p.co) for p in s.points]
|
coords_cam_list += [world_to_camera_view(scn, cam, ob.matrix_world @ p.co) for p in s.points]
|
||||||
|
|
||||||
|
if time() - t0 > timeout:
|
||||||
|
print(f'timeout (more than {timeout}s to calculate) evaluating frame position of objects {oblist}')
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
print(f'No anim')
|
print(f'No anim')
|
||||||
for ob in oblist:
|
for ob in oblist:
|
||||||
|
@ -920,12 +929,16 @@ def get_gp_box_all_frame_selection(oblist=None, scn=None, cam=None):
|
||||||
if l.hide or l.opacity == 0.0:
|
if l.hide or l.opacity == 0.0:
|
||||||
continue
|
continue
|
||||||
for f in l.frames:
|
for f in l.frames:
|
||||||
|
if time() - t0 > timeout:
|
||||||
|
print(f'timeout (more than {timeout}s to calculate) evaluating frame position of objects {oblist}')
|
||||||
|
return
|
||||||
if not (scn.frame_start <= f.frame_number <= scn.frame_end):
|
if not (scn.frame_start <= f.frame_number <= scn.frame_end):
|
||||||
continue
|
continue
|
||||||
for s in f.strokes:
|
for s in f.strokes:
|
||||||
if len(s.points) == 1: # skip isolated points
|
if len(s.points) == 1: # skip isolated points
|
||||||
continue
|
continue
|
||||||
coords_cam_list += [world_to_camera_view(scn, cam, ob.matrix_world @ p.co) for p in s.points]
|
coords_cam_list += [world_to_camera_view(scn, cam, ob.matrix_world @ p.co) for p in s.points]
|
||||||
|
|
||||||
|
|
||||||
print(f'{len(coords_cam_list)} gp points listed {time() - start:.1f}s')
|
print(f'{len(coords_cam_list)} gp points listed {time() - start:.1f}s')
|
||||||
return coords_cam_list
|
return coords_cam_list
|
||||||
|
@ -954,6 +967,9 @@ def set_box_from_selected_objects(scn=None, cam=None, export_json=False):
|
||||||
|
|
||||||
selection = [o for o in scn.objects if o.select_get()] # selected_objects
|
selection = [o for o in scn.objects if o.select_get()] # selected_objects
|
||||||
coords = get_gp_box_all_frame_selection(oblist=selection, scn=scn, cam=cam)
|
coords = get_gp_box_all_frame_selection(oblist=selection, scn=scn, cam=cam)
|
||||||
|
if not coords:
|
||||||
|
return f'Border not set: Timeout during analysis of {len(selection)} objects'
|
||||||
|
|
||||||
_bbox_px = set_border_region_from_coord(coords, margin=30, scn=scn, export_json=export_json)
|
_bbox_px = set_border_region_from_coord(coords, margin=30, scn=scn, export_json=export_json)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1032,6 +1048,8 @@ def split_object_to_scene():
|
||||||
# border to GP objects of the scene
|
# border to GP objects of the scene
|
||||||
gp_objs = [o for o in new.objects if o.type == 'GPENCIL']
|
gp_objs = [o for o in new.objects if o.type == 'GPENCIL']
|
||||||
coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera)
|
coords = get_gp_box_all_frame_selection(oblist=gp_objs, scn=new, cam=new.camera)
|
||||||
|
if not coords:
|
||||||
|
return f'Scene "{scene_name}" created. But Border was not set (Timeout during GP analysis), should be done by hand if needed then use export crop to json'
|
||||||
set_border_region_from_coord(coords, margin=30, scn=new, export_json=True)
|
set_border_region_from_coord(coords, margin=30, scn=new, export_json=True)
|
||||||
|
|
||||||
export_crop_to_json()
|
export_crop_to_json()
|
||||||
|
|
4
ui.py
4
ui.py
|
@ -130,10 +130,10 @@ class GPEXP_PT_gp_node_ui(Panel):
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.label(text='Sub Scenes:')
|
layout.label(text='Sub Scenes:')
|
||||||
layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split To Scene')
|
layout.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selected Obj To Scene')
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Set Crop')
|
row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop')
|
||||||
row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json')
|
row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json')
|
||||||
|
|
||||||
layout.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All Sub-Scene')
|
layout.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All Sub-Scene')
|
||||||
|
|
Loading…
Reference in New Issue