gp_render/OP_check_scene.py

156 lines
5.1 KiB
Python
Raw Normal View History

import bpy, re
from . import fn
def check_broken_modifier_target(pool=None, reports=None):
if not reports:
reports = []
if not pool:
pool = [o for o in bpy.context.scene.objects if o.type == 'GPENCIL']
for o in pool:
lay_name_list = [l.info for l in o.data.layers]
for m in o.grease_pencil_modifiers:
if not hasattr(m, 'layer'):
continue
if not m.layer:
continue
if not m.layer in lay_name_list:
reports.append(f'Broken modifier target :{o.name} > {m.name} > {m.layer}')
# else:
# print(f'Modifier target :{o.name} > {m.name} > ok')
return reports
def check_layer_state(pool=None, reports=None):
if not reports:
reports = []
if not pool:
pool = [o for o in bpy.context.scene.objects if o.type == 'GPENCIL']
for ob in pool:
layers = ob.data.layers
for l in layers:
# if l.mask_layers:
# if not any(not x.hide for x in l.mask_layers):
# # all masks disable
# pass
2023-01-18 14:28:27 +01:00
## just list masks
# state = '' if l.use_mask_layer else ' (disabled)'
# reports.append(f'{ob.name} > {l.info} masks{state}:')
# for ml in l.mask_layers:
# mlstate = ' (disabled)' if ml.hide else ''
# mlinvert = ' <>' if ml.invert else ''
# reports.append(f' - {ml.name}{mlstate}{mlinvert}')
if l.opacity != 1 and not l.info.startswith('MA_'):
reports.append(f'{ob.name} > {l.info} > opacity {l.opacity}')
# if l.use_lights:
# reports.append(f'-> use lights !')
if l.blend_mode != 'REGULAR':
reports.append(f'{ob.name} > {l.info} > blend mode "{l.blend_mode}" !')
return reports
def check_file_output_numbering(reports=None):
if not reports:
reports = []
prenum = re.compile(r'\d{3}_')
file_outs = []
for S in bpy.data.scenes:
if S.name == 'Scene' or not S.node_tree or not S.use_nodes:
continue
file_outs += [n for n in S.node_tree.nodes if n.type == 'OUTPUT_FILE']
2023-01-18 14:28:27 +01:00
if not file_outs:
reports.append('No file output nodes found')
return reports
for fo in file_outs:
if not prenum.match(fo.base_path.split('/')[-1]):
reports.append(f'No object numbering : node {fo.name}')
pct = 0
if fo.format.file_format == 'OPEN_EXR_MULTILAYER':
## multilayer use layer_slots > slot.name
slots = fo.layer_slots
for fs in slots:
if not prenum.match(fs.name.split('/')[0]):
pct += 1
else:
## classic use file_slots > path
slots = fo.file_slots
for fs in slots:
if not prenum.match(fs.path.split('/')[0]):
pct += 1
if pct:
reports.append(f'{pct}/{len(slots)} slots not numbered: node {fo.name}')
return reports
class GPEXP_OT_check_render_scene(bpy.types.Operator):
bl_idname = "gp.check_render_scene"
bl_label = "Check render scene"
bl_description = "Auto check render scene"
bl_options = {"REGISTER"} # , "UNDO"
2023-01-18 14:28:27 +01:00
# clear_unused_view_layers : bpy.props.BoolProperty(name="Clear unused view layers",
# description="Delete view layer that aren't used in the nodetree anymore",
# default=True)
@classmethod
def poll(cls, context):
return True
def invoke(self, context, event):
return self.execute(context)
# return context.window_manager.invoke_props_dialog(self)
# def draw(self, context):
# layout = self.layout
# # layout.prop(self, 'clear_unused_view_layers')
2023-01-18 14:28:27 +01:00
def execute(self, context):
reports = []
# check gp modifiers
broken_mods = check_broken_modifier_target()
if broken_mods:
reports.append('GP modifiers targets:')
reports += broken_mods
2023-01-18 14:28:27 +01:00
# check layers
layer_state = check_layer_state()
if layer_state:
if reports: reports.append('')
reports.append('Layers State:')
reports += layer_state
# check file output numbering
numbering_problems = check_file_output_numbering()
if numbering_problems:
if reports: reports.append('')
reports.append('File output numbering:')
reports += numbering_problems
if not reports:
self.report({'INFO'}, 'All OK !')
reports.append('Everything Ok !')
if hasattr(bpy.types, 'GP_OT_file_checker'):
# propose to run toolbox checker if exists
reports.append(['gp.file_checker', 'Run GP_toolbox File Checker', 'SCENE_DATA'])
fn.show_message_box(_message=reports, _title='Potential Problems list')
return {"FINISHED"}
classes=(
GPEXP_OT_check_render_scene,
)
2023-01-18 14:28:27 +01:00
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)