Check file visibility conflicts check

1.7.2

- added: `Object visibility conflict` in file check
  - print in console when object have render activated but not viewport (& vice-versa)
  - Standalone ops "List Object Visibility Conflicts" (`gp.list_object_visibility`)
- added: `GP Modifier visibility conflict` in file check.
  - print in console when gp modifiers have render activated but not viewport (& vice-versa)
  - Standalone ops "List GP Modifiers Visibility Conflicts" (`gp.list_modifier_visibility`)
- code: show_message_box utils can now receive operator in sublist (if 3 element)
This commit is contained in:
Pullusb
2021-10-20 20:54:59 +02:00
parent b62a23858c
commit 4c6bd20b60
6 changed files with 220 additions and 47 deletions
+178 -44
View File
@@ -1,17 +1,13 @@
import bpy
import os
from pathlib import Path
from .utils import show_message_box, get_addon_prefs
from . import utils
class GPTB_OT_file_checker(bpy.types.Operator):
bl_idname = "gp.file_checker"
bl_label = "File check"
bl_label = "Check File"
bl_description = "Check / correct some aspect of the file, properties and such and report"
bl_options = {"REGISTER"}
# @classmethod
# def poll(cls, context):
# return context.region_data.view_perspective == 'CAMERA'
## list of action :
# Lock main cam:
@@ -23,16 +19,19 @@ class GPTB_OT_file_checker(bpy.types.Operator):
# GP use additive drawing (else creating a frame in dopesheet makes it blank...)
# GP stroke placement/projection check
# Disabled animation
# Object visibility conflict
# GP modifiers visibility conflict
# Set onion skin filter to 'All type'
# Set filepath type
# Set Lock object mode state
def invoke(self, context, event):
# need some self-control (I had to...)
self.ctrl = event.ctrl
return self.execute(context)
def execute(self, context):
prefs = get_addon_prefs()
prefs = utils.get_addon_prefs()
fix = prefs.fixprops
problems = []
@@ -128,7 +127,37 @@ class GPTB_OT_file_checker(bpy.types.Operator):
fcu_ct += 1
print(f"muted: {act.name} > {fcu.data_path}")
if fcu_ct:
problems.append(f'{fcu_ct} anim channel disabled (details -> console)')
problems.append(f'{fcu_ct} anim channel disabled (details in console)')
## Object visibility conflict
if fix.list_obj_vis_conflict:
viz_ct = 0
for o in context.scene.objects:
if o.hide_viewport != o.hide_render:
vp = 'No' if o.hide_viewport else 'Yes'
rd = 'No' if o.hide_render else 'Yes'
viz_ct += 1
print(f'{o.name} : viewport {vp} != render {rd}')
if viz_ct:
## warn only : problems.append(f'{viz_ct} objects visibility conflicts (details in console)')
problems.append(['gp.list_object_visibility', f'{viz_ct} objects visibility conflicts (details in console)', 'OBJECT_DATAMODE'])
## GP modifiers visibility conflict
if fix.list_gp_mod_vis_conflict:
mod_viz_ct = 0
for o in context.scene.objects:
if o.type != 'GPENCIL':
continue
for m in o.grease_pencil_modifiers:
if m.show_viewport != m.show_render:
vp = 'Yes' if m.show_viewport else 'No'
rd = 'Yes' if m.show_render else 'No'
mod_viz_ct += 1
print(f'{o.name} - modifier {m.name}: viewport {vp} != render {rd}')
if mod_viz_ct:
## warn only : problems.append(f'{mod_viz_ct} visibility conflicts in Gp object modifiers (details in console)')
problems.append(['gp.list_modifier_visibility', f'{mod_viz_ct} visibility conflicts in Gp object modifiers (details in console)', 'MODIFIER_DATA'])
## Use median point
if fix.set_pivot_median_point:
@@ -205,47 +234,12 @@ class GPTB_OT_file_checker(bpy.types.Operator):
# Show in viewport
title = "Changed Settings" if apply else "Checked Settings (dry run, nothing changed)"
show_message_box(problems, _title = title, _icon = 'INFO')
utils.show_message_box(problems, _title = title, _icon = 'INFO')
else:
self.report({'INFO'}, 'All good')
return {"FINISHED"}
""" OLD links checker with show_message_box
class GPTB_OT_links_checker(bpy.types.Operator):
bl_idname = "gp.links_checker"
bl_label = "Links check"
bl_description = "Check states of file direct links"
bl_options = {"REGISTER"}
def execute(self, context):
all_lnks = []
has_broken_link = False
## check for broken links
for current, lib in zip(bpy.utils.blend_paths(local=True), bpy.utils.blend_paths(absolute=True, local=True)):
lfp = Path(lib)
realib = Path(current)
if not lfp.exists():
has_broken_link = True
all_lnks.append( (f"Broken link: {realib.as_posix()}", 'LIBRARY_DATA_BROKEN') )#lfp.as_posix()
else:
if realib.as_posix().startswith('//'):
all_lnks.append( (f"Link: {realib.as_posix()}", 'LINKED') )#lfp.as_posix()
else:
all_lnks.append( (f"Link: {realib.as_posix()}", 'LIBRARY_DATA_INDIRECT') )#lfp.as_posix()
all_lnks.sort(key=lambda x: x[1], reverse=True)
if all_lnks:
print('===File check===')
for p in all_lnks:
if isinstance(p, str):
print(p)
else:
print(p[0])
# Show in viewport
show_message_box(all_lnks, _title = "Links", _icon = 'INFO')
return {"FINISHED"} """
class GPTB_OT_links_checker(bpy.types.Operator):
bl_idname = "gp.links_checker"
@@ -332,6 +326,144 @@ class GPTB_OT_links_checker(bpy.types.Operator):
self.proj = None
return context.window_manager.invoke_props_dialog(self, width=800)
""" OLD links checker with show_message_box
class GPTB_OT_links_checker(bpy.types.Operator):
bl_idname = "gp.links_checker"
bl_label = "Links check"
bl_description = "Check states of file direct links"
bl_options = {"REGISTER"}
def execute(self, context):
all_lnks = []
has_broken_link = False
## check for broken links
for current, lib in zip(bpy.utils.blend_paths(local=True), bpy.utils.blend_paths(absolute=True, local=True)):
lfp = Path(lib)
realib = Path(current)
if not lfp.exists():
has_broken_link = True
all_lnks.append( (f"Broken link: {realib.as_posix()}", 'LIBRARY_DATA_BROKEN') )#lfp.as_posix()
else:
if realib.as_posix().startswith('//'):
all_lnks.append( (f"Link: {realib.as_posix()}", 'LINKED') )#lfp.as_posix()
else:
all_lnks.append( (f"Link: {realib.as_posix()}", 'LIBRARY_DATA_INDIRECT') )#lfp.as_posix()
all_lnks.sort(key=lambda x: x[1], reverse=True)
if all_lnks:
print('===File check===')
for p in all_lnks:
if isinstance(p, str):
print(p)
else:
print(p[0])
# Show in viewport
utils.show_message_box(all_lnks, _title = "Links", _icon = 'INFO')
return {"FINISHED"} """
class GPTB_OT_list_object_visibility(bpy.types.Operator):
bl_idname = "gp.list_object_visibility"
bl_label = "List Object Visibility Conflicts"
bl_description = "List objects visibility conflicts, when viewport and render have different values"
bl_options = {"REGISTER"}
def invoke(self, context, event):
self.ob_list = [o for o in context.scene.objects if o.hide_viewport != o.hide_render]
return context.window_manager.invoke_props_dialog(self, width=250)
def draw(self, context):
layout = self.layout
for o in self.ob_list:
row = layout.row()
row.label(text=o.name)
row.prop(o, 'hide_viewport', text='', emboss=False) # invert_checkbox=True
row.prop(o, 'hide_render', text='', emboss=False) # invert_checkbox=True
def execute(self, context):
return {'FINISHED'}
## basic listing as message box # all in invoke now
# li = []
# viz_ct = 0
# for o in context.scene.objects:
# if o.hide_viewport != o.hide_render:
# vp = 'No' if o.hide_viewport else 'Yes'
# rd = 'No' if o.hide_render else 'Yes'
# viz_ct += 1
# li.append(f'{o.name} : viewport {vp} != render {rd}')
# if li:
# utils.show_message_box(_message=li, _title=f'{viz_ct} visibility conflicts found')
# else:
# self.report({'INFO'}, f"No Object visibility conflict on current scene")
# return {'FINISHED'}
## not exposed in UI, Check is performed in Check file (can be called in popped menu)
class GPTB_OT_list_modifier_visibility(bpy.types.Operator):
bl_idname = "gp.list_modifier_visibility"
bl_label = "List GP Modifiers Visibility Conflicts"
bl_description = "List Modifier visibility conflicts, when viewport and render have different values"
bl_options = {"REGISTER"}
def invoke(self, context, event):
self.ob_list = []
for o in context.scene.objects:
if o.type != 'GPENCIL':
continue
if not len(o.grease_pencil_modifiers):
continue
mods = []
for m in o.grease_pencil_modifiers:
if m.show_viewport != m.show_render:
if not mods:
self.ob_list.append([o, mods])
mods.append(m)
return context.window_manager.invoke_props_dialog(self, width=250)
def draw(self, context):
layout = self.layout
for o in self.ob_list:
layout.label(text=o[0].name, icon='OUTLINER_OB_GREASEPENCIL')
for m in o[1]:
row = layout.row()
row.label(text='')
row.label(text=m.name, icon='MODIFIER_ON')
row.prop(m, 'show_viewport', text='', emboss=False) # invert_checkbox=True
row.prop(m, 'show_render', text='', emboss=False) # invert_checkbox=True
def execute(self, context):
return {'FINISHED'}
## basic listing as message box # all in invoke now
# li = []
# oblist = []
# if self.selection:
# pool = context.selected_objects
# else:
# pool = context.scene.objects
# for o in pool:
# if o.type != 'GPENCIL':
# continue
# for m in o.grease_pencil_modifiers:
# if m.show_viewport != m.show_render:
# if o not in oblist:
# oblist.append(o)
# li.append(o.name) # just name first time to list mods after
# vp = 1 if m.show_viewport else 0
# rd = 1 if m.show_render else 0
# mess = f' - modifier {m.name}: viewport {vp} != render {rd}'
# # mess = f'{o.name} - modifier {m.name}: viewport {vp} != render {rd}'
# li.append(mess)
# if li:
# utils.show_message_box(li)
# else:
# self.report({'INFO'}, f"No Gp modifier visibility conflict on {'selection' if self.selection else 'scene'}")
# return {'FINISHED'}
'''### OLD
class GPTB_OT_check_scene(bpy.types.Operator):
bl_idname = "gp.scene_check"
@@ -367,6 +499,8 @@ class GPTB_OT_check_scene(bpy.types.Operator):
classes = (
# GPTB_OT_check_scene,
GPTB_OT_list_object_visibility,
GPTB_OT_list_modifier_visibility,
GPTB_OT_file_checker,
GPTB_OT_links_checker,
)