ignore object with leading dot
1.0.2 - added: GP object with name starting with `.` are ignored from "all objects" operation (renaming, numbering, sending to render scene) - temporarily, layer named `note` (case insensitive) are ignored as well. This should be removed in later version to keep only dot exculsion rule.main
parent
b6e695eef3
commit
8a5654e977
|
@ -14,6 +14,11 @@ Activate / deactivate layer opacity according to prefix
|
|||
Activate / deactivate all masks using MA layers
|
||||
-->
|
||||
|
||||
1.0.2
|
||||
|
||||
- added: GP object with name starting with `.` are ignored from "all objects" operation (renaming, numbering, sending to render scene)
|
||||
- temporarily, layer named `note` (case insensitive) are ignored as well. This should be removed in later version to keep only dot exculsion rule.
|
||||
|
||||
1.0.1
|
||||
|
||||
- fix: `Export Camera 2D Position To AE` file format not working on windows when export from linux (add CRLF terminator to generated text file)
|
||||
|
|
|
@ -90,7 +90,7 @@ class GPEXP_OT_add_objects_to_render(bpy.types.Operator):
|
|||
# if not scn:
|
||||
# self.report({'ERROR'}, 'Could not found default scene')
|
||||
# return {"CANCELLED"}
|
||||
export_gp_objects([o for o in context.scene.objects if o.type == 'GPENCIL' and not o.hide_get()], exclude_list=excludes, scene=scn)
|
||||
export_gp_objects([o for o in context.scene.objects if o.type == 'GPENCIL' and not o.hide_get() and fn.is_valid_name(o.name)], exclude_list=excludes, scene=scn)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
import bpy
|
||||
from . import gen_vlayer, fn
|
||||
|
||||
class GPEXP_OT_render_auto_build(bpy.types.Operator):
|
||||
bl_idname = "gp_export.render_auto_build"
|
||||
bl_label = "Auto-Build"
|
||||
bl_description = "Trigger all operation to make build render scene with default settings"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.object and context.object.type == 'GPENCIL'
|
||||
|
||||
# mode : bpy.props.StringProperty(options={'SKIP_SAVE'})
|
||||
|
||||
def execute(self, context):
|
||||
'''
|
||||
ob = context.object
|
||||
layer = ob.data.layers.active
|
||||
if not layer:
|
||||
self.report({'ERROR'}, 'No active layer')
|
||||
return {"CANCELLED"}
|
||||
|
||||
ct = 0
|
||||
# send scene ?
|
||||
hided = 0
|
||||
for l in ob.data.layers:
|
||||
if not l.select:
|
||||
if not l.viewlayer_render:
|
||||
l.viewlayer_render = fn.get_view_layer('exclude').name
|
||||
continue
|
||||
gen_vlayer.get_set_viewlayer_from_gp(ob, l)
|
||||
|
||||
if l.hide:
|
||||
hided += 1
|
||||
ct += 1
|
||||
|
||||
if hided:
|
||||
self.report({'WARNING'}, f'{hided}/{ct} layers are hided !')
|
||||
|
||||
else:
|
||||
self.report({'INFO'}, f'{ct} layer(s) added to scene "Render"')
|
||||
'''
|
||||
|
||||
## TODO: add colors to layers (specified in ENV or hardcoded for now...)
|
||||
## Option: Maybe find a way to create a color from prefix hash ? (wlways give unique color with same prefix on other project!)
|
||||
|
||||
|
||||
## Trigger rename lowercase
|
||||
bpy.ops.gp.lower_layers_name()
|
||||
|
||||
## Trigger renumber by distance
|
||||
bpy.ops.gp.auto_number_object()
|
||||
|
||||
## Export layer infos ?
|
||||
bpy.ops.gp.export_infos_for_compo()
|
||||
|
||||
## Send all GP to render scene
|
||||
bpy.ops.gp.add_object_to_render(mode="ALL")
|
||||
|
||||
## Group all adjacent layer type
|
||||
|
||||
## Renumber File outputs
|
||||
|
||||
## Trigger check file before finishing ?
|
||||
|
||||
|
||||
## note: After all these operation, a ctrl+Z might crash
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
classes=(
|
||||
GPEXP_OT_render_auto_build,
|
||||
)
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
|
@ -76,7 +76,7 @@ class GPEXP_OT_export_infos_for_compo(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
dic = {}
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
for o in pool:
|
||||
# if not o.visible_get():
|
||||
# continue
|
||||
|
@ -186,8 +186,6 @@ class GPEXP_OT_layers_state(bpy.types.Operator):
|
|||
return context.object and context.object.type == 'GPENCIL'
|
||||
|
||||
def invoke(self, context, event):
|
||||
if event.alt:
|
||||
self.all_objects=True
|
||||
|
||||
## if no existing infos.json generated, call ops
|
||||
l_infos = Path(bpy.data.filepath).parent / 'render' / 'infos.json'
|
||||
|
@ -219,7 +217,7 @@ class GPEXP_OT_layers_state(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
if self.all_objects:
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
else:
|
||||
pool = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||
# pool = [context.object]
|
||||
|
@ -326,7 +324,7 @@ class GPEXP_OT_lower_layers_name(bpy.types.Operator):
|
|||
return context.object and context.object.type == 'GPENCIL'
|
||||
|
||||
all_objects : BoolProperty(name='On All Object',
|
||||
default=False, description='On All object, else use selected objects') # , options={'SKIP_SAVE'}
|
||||
default=True, description='On All object, else use selected objects') # , options={'SKIP_SAVE'}
|
||||
|
||||
object_name : BoolProperty(name='Normalize Object Name',
|
||||
default=True, description='Make the object name lowercase') # , options={'SKIP_SAVE'}
|
||||
|
@ -349,7 +347,7 @@ class GPEXP_OT_lower_layers_name(bpy.types.Operator):
|
|||
layout = self.layout
|
||||
layout.prop(self, 'all_objects')
|
||||
if self.all_objects:
|
||||
gp_ct = len([o for o in context.scene.objects if o.type == 'GPENCIL'])
|
||||
gp_ct = len([o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)])
|
||||
else:
|
||||
gp_ct = len([o for o in context.selected_objects if o.type == 'GPENCIL'])
|
||||
|
||||
|
@ -367,7 +365,7 @@ class GPEXP_OT_lower_layers_name(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
if self.all_objects:
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
else:
|
||||
pool = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||
|
||||
|
@ -387,6 +385,7 @@ class GPEXP_OT_lower_layers_name(bpy.types.Operator):
|
|||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class GPEXP_OT_auto_number_object(bpy.types.Operator):
|
||||
bl_idname = "gp.auto_number_object"
|
||||
bl_label = "Auto Number Object"
|
||||
|
@ -398,7 +397,7 @@ class GPEXP_OT_auto_number_object(bpy.types.Operator):
|
|||
return context.object and context.object.type == 'GPENCIL'
|
||||
|
||||
all_objects : BoolProperty(name='On All GP Object',
|
||||
default=False, description='On All object, else use selected Grease Pencil objects') # , options={'SKIP_SAVE'}
|
||||
default=True, description='On All object, else use selected Grease Pencil objects') # , options={'SKIP_SAVE'}
|
||||
|
||||
rename_data : BoolProperty(name='Rename Gpencil Data',
|
||||
default=True, description='Rename Also the Grease Pencil data using same name as object') # , options={'SKIP_SAVE'}
|
||||
|
@ -411,7 +410,7 @@ class GPEXP_OT_auto_number_object(bpy.types.Operator):
|
|||
if event.ctrl or self.delete:
|
||||
regex_num = re.compile(r'^(\d{3})_')
|
||||
ct = 0
|
||||
gps = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||
gps = [o for o in context.selected_objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
for o in gps:
|
||||
if regex_num.match(o.name):
|
||||
o.name = o.name[4:]
|
||||
|
@ -426,7 +425,7 @@ class GPEXP_OT_auto_number_object(bpy.types.Operator):
|
|||
layout = self.layout
|
||||
layout.prop(self, 'all_objects')
|
||||
if self.all_objects:
|
||||
gp_ct = len([o for o in context.scene.objects if o.type == 'GPENCIL'])
|
||||
gp_ct = len([o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)])
|
||||
else:
|
||||
gp_ct = len([o for o in context.selected_objects if o.type == 'GPENCIL'])
|
||||
|
||||
|
@ -437,7 +436,7 @@ class GPEXP_OT_auto_number_object(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
if self.all_objects:
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
else:
|
||||
pool = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||
|
||||
|
@ -497,7 +496,7 @@ class GPEXP_OT_check_masks(bpy.types.Operator):
|
|||
# else:
|
||||
# pool = [o for o in context.selected_objects if o.type == 'GPENCIL']
|
||||
changes = []
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL']
|
||||
pool = [o for o in context.scene.objects if o.type == 'GPENCIL' and fn.is_valid_name(o.name)]
|
||||
for o in pool:
|
||||
for l in o.data.layers:
|
||||
if l.use_mask_layer:
|
||||
|
|
60
__init__.py
60
__init__.py
|
@ -2,7 +2,7 @@ bl_info = {
|
|||
"name": "GP Render",
|
||||
"description": "Organise export of gp layers through compositor output",
|
||||
"author": "Samuel Bernou",
|
||||
"version": (1, 0, 1),
|
||||
"version": (1, 0, 2),
|
||||
"blender": (2, 93, 0),
|
||||
"location": "View3D",
|
||||
"warning": "",
|
||||
|
@ -26,10 +26,31 @@ from . import OP_render_pdf
|
|||
from . import OP_export_to_ae
|
||||
from . import prefs
|
||||
from . import OP_setup_layers
|
||||
from . import OP_auto_build
|
||||
from . import ui
|
||||
|
||||
from .fn import scene_aa
|
||||
|
||||
bl_modules = (
|
||||
prefs,
|
||||
OP_add_layer,
|
||||
OP_clear,
|
||||
OP_clean,
|
||||
OP_connect_toggle,
|
||||
OP_merge_layers,
|
||||
OP_manage_outputs,
|
||||
OP_scene_switch,
|
||||
OP_crop_to_object,
|
||||
OP_render_scenes,
|
||||
OP_check_scene,
|
||||
OP_post_render,
|
||||
OP_render_pdf,
|
||||
OP_export_to_ae,
|
||||
OP_setup_layers,
|
||||
OP_auto_build,
|
||||
ui,
|
||||
)
|
||||
|
||||
def update_scene_aa(context, scene):
|
||||
scene_aa(toggle=bpy.context.scene.use_aa)
|
||||
|
||||
|
@ -39,22 +60,9 @@ def register():
|
|||
if bpy.app.background:
|
||||
return
|
||||
|
||||
prefs.register()
|
||||
OP_add_layer.register()
|
||||
OP_clear.register()
|
||||
OP_clean.register()
|
||||
OP_connect_toggle.register()
|
||||
OP_merge_layers.register()
|
||||
OP_manage_outputs.register()
|
||||
OP_scene_switch.register()
|
||||
OP_crop_to_object.register()
|
||||
OP_render_scenes.register()
|
||||
OP_check_scene.register()
|
||||
OP_post_render.register()
|
||||
OP_render_pdf.register()
|
||||
OP_export_to_ae.register()
|
||||
OP_setup_layers.register()
|
||||
ui.register()
|
||||
for mod in bl_modules:
|
||||
mod.register()
|
||||
|
||||
# bpy.types.Scene.pgroup_name = bpy.props.PointerProperty(type = PROJ_PGT_settings)
|
||||
bpy.types.Scene.use_aa = bpy.props.BoolProperty(
|
||||
name='Use Native Anti Aliasing',
|
||||
|
@ -69,22 +77,8 @@ def unregister():
|
|||
if bpy.app.background:
|
||||
return
|
||||
|
||||
ui.unregister()
|
||||
OP_setup_layers.unregister()
|
||||
OP_check_scene.unregister()
|
||||
OP_post_render.unregister()
|
||||
OP_export_to_ae.unregister()
|
||||
OP_render_pdf.unregister()
|
||||
OP_render_scenes.unregister()
|
||||
OP_crop_to_object.unregister()
|
||||
OP_scene_switch.unregister()
|
||||
OP_manage_outputs.unregister()
|
||||
OP_merge_layers.unregister()
|
||||
OP_connect_toggle.unregister()
|
||||
OP_clean.unregister()
|
||||
OP_clear.unregister()
|
||||
OP_add_layer.unregister()
|
||||
prefs.unregister()
|
||||
for mod in reversed(bl_modules):
|
||||
mod.unregister()
|
||||
|
||||
del bpy.types.Scene.use_aa
|
||||
|
||||
|
|
17
fn.py
17
fn.py
|
@ -10,6 +10,23 @@ from time import time
|
|||
import json
|
||||
|
||||
|
||||
### -- rules
|
||||
|
||||
def is_valid_name(name):
|
||||
'''return True if name correspond to a valid object
|
||||
Don't start with a dot '.'
|
||||
Is not "note"
|
||||
'''
|
||||
|
||||
if name.startswith('.'):
|
||||
return False
|
||||
|
||||
## FIXME: /!\ "note" as an exclude word is not good practice, temporary fix
|
||||
if name.lower() == 'note':
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
### -- node basic
|
||||
|
||||
def create_node(type, tree=None, **kargs):
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
info = {
|
||||
'icon': 'AUTO',
|
||||
'description': 'Setup things to make the precomp roll and rock'
|
||||
}
|
||||
|
||||
import bpy
|
||||
import os, subprocess
|
||||
import re, fnmatch, glob
|
||||
from pathlib import Path
|
||||
from os.path import join, dirname, basename, exists, isfile, isdir, splitext
|
||||
from mathutils import Vector, Matrix
|
||||
from math import radians, degrees
|
||||
|
||||
C = bpy.context
|
||||
D = bpy.data
|
||||
scn = bpy.context.scene
|
||||
|
||||
## v0.1
|
||||
## - Setup layer colors
|
||||
|
||||
## TODO
|
||||
# - Update libraries
|
||||
# - Import Fx3D (or render from Fx3D file... maybe easier consifering the number)
|
||||
|
||||
|
||||
## tried to make color that fit in White theme
|
||||
## (difficult for readability since this text color is not the same)
|
||||
|
||||
|
||||
prefix_color = {
|
||||
# 'MA_': (0.09, 0.08, 0.46), # Vivid blue
|
||||
'MA_': (0.65, 0.4, 0.6), # Pink Light
|
||||
|
||||
'FX_': (0.12, 0.33, 0.58), # (0.3, 0.49, 0.63) # Blue Light
|
||||
# 'CO_': (0.35, 0.0085, 0.25),
|
||||
'CO_': (0.5,0.1,0.5), # Clear Pink
|
||||
# 'CU': (0.092070, 0.177356, 0.447959), # Blue clear
|
||||
'CU_': (0.02, 0.27, 0.27), # Indigo
|
||||
}
|
||||
|
||||
## UW -> TO (here used fo CU): (0.015996, 0.246201, 0.246201) # Indigo
|
||||
|
||||
## invisible (close to violet light) in UW: (0.246201, 0.132868, 0.496933)
|
||||
|
||||
|
||||
def set_layer_colors():
|
||||
for ob in scn.objects:
|
||||
if ob.type != 'GPENCIL':
|
||||
continue
|
||||
for l in ob.data.layers:
|
||||
# if l.info.startswith(prefix_color.keys()):
|
||||
color = prefix_color.get(l.info[:3])
|
||||
if not color:
|
||||
continue
|
||||
print(l.info, '->', color)
|
||||
l.channel_color = color
|
||||
|
||||
C.preferences.edit.use_anim_channel_group_colors = True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set_layer_colors()
|
||||
|
||||
## update libraries
|
||||
bpy.ops.gadget.update_libraries()
|
4
ui.py
4
ui.py
|
@ -173,6 +173,9 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
## TODO: add auto-build
|
||||
# layout.operator('gp_export.render_auto_build')
|
||||
if context.object:
|
||||
layout.label(text=f'Object: {context.object.name}')
|
||||
if context.object.data.users > 1:
|
||||
|
@ -203,7 +206,6 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
|
|||
row.operator('gp.merge_viewlayers_to_active', text=txt, icon='SELECT_EXTEND')
|
||||
row.enabled= ct > 1
|
||||
|
||||
|
||||
## all and objects
|
||||
layout.separator()
|
||||
|
||||
|
|
Loading…
Reference in New Issue