parent
fd91900328
commit
b1cc4fa5d7
|
@ -14,6 +14,10 @@ Activate / deactivate layer opacity according to prefix
|
||||||
Activate / deactivate all masks using MA layers
|
Activate / deactivate all masks using MA layers
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
1.1.3
|
||||||
|
|
||||||
|
- added: clean material stack in auto-build
|
||||||
|
|
||||||
1.1.2
|
1.1.2
|
||||||
|
|
||||||
- added: popup panel with options for autobuild
|
- added: popup panel with options for autobuild
|
||||||
|
|
|
@ -64,8 +64,11 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||||
clean_name_and_visibility : bpy.props.BoolProperty(name='Clean Name And Visibility', default=True,
|
clean_name_and_visibility : bpy.props.BoolProperty(name='Clean Name And Visibility', default=True,
|
||||||
description='Add object name to layer name when there is only prefix (ex: "CO_")\
|
description='Add object name to layer name when there is only prefix (ex: "CO_")\
|
||||||
\nEnable visibility for layer with prefix included in Prefix Filter')
|
\nEnable visibility for layer with prefix included in Prefix Filter')
|
||||||
|
|
||||||
|
clean_material_duplication : bpy.props.BoolProperty(name='Clean Material Duplication', default=True,
|
||||||
|
description='Clean material stack. i.e: Replace "mat.001" in material stack if "mat" exists and has same color')
|
||||||
|
|
||||||
prefix_filter : bpy.props.StringProperty(name='Prefix Filter', default='CO, CU, FX, TO, MA',
|
prefix_filter : bpy.props.StringProperty(name='Prefix Filter', default='CO, CU, FX, TO', # , MA # exclude MA if mask are applied
|
||||||
description='Comma separated prefix to render. Set the other prefix and non-prefixed layer to exluded viewlayer')
|
description='Comma separated prefix to render. Set the other prefix and non-prefixed layer to exluded viewlayer')
|
||||||
|
|
||||||
set_layers_colors : bpy.props.BoolProperty(name='Set Layers Colors', default=True,
|
set_layers_colors : bpy.props.BoolProperty(name='Set Layers Colors', default=True,
|
||||||
|
@ -98,6 +101,7 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.prop(self, 'clean_name_and_visibility')
|
col.prop(self, 'clean_name_and_visibility')
|
||||||
|
col.prop(self, 'clean_material_duplication')
|
||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(self, 'prefix_filter')
|
row.prop(self, 'prefix_filter')
|
||||||
row.active = self.clean_name_and_visibility
|
row.active = self.clean_name_and_visibility
|
||||||
|
@ -129,9 +133,10 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||||
self.report({'ERROR'}, 'A "Render" scene already exists')
|
self.report({'ERROR'}, 'A "Render" scene already exists')
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
all_gp_objects = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||||
## clean name and visibility
|
## clean name and visibility
|
||||||
if self.clean_name_and_visibility:
|
if self.clean_name_and_visibility:
|
||||||
for o in [o for o in context.scene.objects if o.type == 'GPENCIL']:
|
for o in all_gp_objects:
|
||||||
if o.hide_render:
|
if o.hide_render:
|
||||||
print(f'skip: {o.name} hide render')
|
print(f'skip: {o.name} hide render')
|
||||||
continue
|
continue
|
||||||
|
@ -145,8 +150,13 @@ class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||||
if res.group(1) in prefix_to_render and l.hide == True:
|
if res.group(1) in prefix_to_render and l.hide == True:
|
||||||
print(f'{o.name} -> {l.info} : Switch visibility On')
|
print(f'{o.name} -> {l.info} : Switch visibility On')
|
||||||
l.hide = False
|
l.hide = False
|
||||||
|
|
||||||
ob_list = [o for o in context.scene.objects if o.type == 'GPENCIL' and not o.hide_get() and fn.is_valid_name(o.name)]
|
if self.clean_material_duplication:
|
||||||
|
print('Clean material duplicates')
|
||||||
|
for ob in all_gp_objects:
|
||||||
|
fn.clean_mats_duplication(ob)
|
||||||
|
|
||||||
|
ob_list = [o for o in all_gp_objects if not o.hide_get() and fn.is_valid_name(o.name)]
|
||||||
if not ob_list:
|
if not ob_list:
|
||||||
self.report({'ERROR'}, 'No GP object to render found')
|
self.report({'ERROR'}, 'No GP object to render found')
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
|
@ -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": (1, 1, 2),
|
"version": (1, 1, 3),
|
||||||
"blender": (2, 93, 0),
|
"blender": (2, 93, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
62
fn.py
62
fn.py
|
@ -1576,4 +1576,64 @@ def set_layer_colors(skip_if_colored=False):
|
||||||
print(l.info, '->', color)
|
print(l.info, '->', color)
|
||||||
l.channel_color = color
|
l.channel_color = color
|
||||||
|
|
||||||
bpy.context.preferences.edit.use_anim_channel_group_colors = True
|
bpy.context.preferences.edit.use_anim_channel_group_colors = True
|
||||||
|
|
||||||
|
|
||||||
|
def different_gp_mat(mata, matb):
|
||||||
|
'''return None if no difference (False), string describing color difference (True)'''
|
||||||
|
a = mata.grease_pencil
|
||||||
|
b = matb.grease_pencil
|
||||||
|
if a.color[:] != b.color[:]:
|
||||||
|
return f'{mata.name} and {matb.name} stroke color is different'
|
||||||
|
if a.fill_color[:] != b.fill_color[:]:
|
||||||
|
return f'{mata.name} and {matb.name} fill_color color is different'
|
||||||
|
if a.show_stroke != b.show_stroke:
|
||||||
|
return f'{mata.name} and {matb.name} stroke has different state'
|
||||||
|
if a.show_fill != b.show_fill:
|
||||||
|
return f'{mata.name} and {matb.name} fill has different state'
|
||||||
|
|
||||||
|
## Clean dups
|
||||||
|
def clean_mats_duplication(ob, skip_different_materials=True):
|
||||||
|
'''Clean object material stack of duplication
|
||||||
|
if a material is named "mat.001" and a "mat" exists, replace with the one with original name
|
||||||
|
|
||||||
|
:skip_different_materials: Don't replace a "mat.???" if orignal "mat" has different color
|
||||||
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
diff_ct = 0
|
||||||
|
todel = []
|
||||||
|
if ob.type != 'GPENCIL':
|
||||||
|
return
|
||||||
|
if not hasattr(ob, 'material_slots'):
|
||||||
|
return
|
||||||
|
for i, ms in enumerate(ob.material_slots):
|
||||||
|
mat = ms.material
|
||||||
|
if not mat:
|
||||||
|
continue
|
||||||
|
match = re.search(r'(.*)\.\d{3}$', mat.name)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
basemat = bpy.data.materials.get(match.group(1))
|
||||||
|
if not basemat:
|
||||||
|
continue
|
||||||
|
diff = different_gp_mat(mat, basemat)
|
||||||
|
if diff:
|
||||||
|
print(f'! {ob.name} : {diff}')
|
||||||
|
diff_ct += 1
|
||||||
|
if skip_different_materials:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if mat not in todel:
|
||||||
|
todel.append(mat)
|
||||||
|
ms.material = basemat
|
||||||
|
print(f'{ob.name} : slot {i} >> replaced {mat.name}')
|
||||||
|
mat.use_fake_user = False
|
||||||
|
|
||||||
|
### delete (only when using on all objects loop, else can delete another objects mat...)
|
||||||
|
## for m in reversed(todel):
|
||||||
|
## bpy.data.materials.remove(m)
|
||||||
|
|
||||||
|
if diff_ct:
|
||||||
|
print(f'{diff_ct} mat skipped >> same name but different color settings!')
|
||||||
|
# return ('INFO', f'{diff_ct} mat skipped >> same name but different color settings!')
|
Loading…
Reference in New Issue