Fix playblast with api changes
2.0.0 - fix: error using playblast (api changes of Blender 3.0+)gpv2
parent
f36b31e3aa
commit
bf60370ab0
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
2.0.0
|
||||
|
||||
- fix: error using playblast (api changes of Blender 3.0+)
|
||||
|
||||
1.9.9
|
||||
|
||||
- fix: Bug setting GP layers actions on/off
|
||||
|
|
|
@ -40,6 +40,8 @@ exclude = (
|
|||
'audio_bitrate',
|
||||
]
|
||||
"""
|
||||
|
||||
'''
|
||||
def render_with_restore():
|
||||
class RenderFileRestorer:
|
||||
rd = bpy.context.scene.render
|
||||
|
@ -80,8 +82,47 @@ def render_with_restore():
|
|||
|
||||
|
||||
return RenderFileRestorer()
|
||||
'''
|
||||
|
||||
|
||||
class render_with_restore:
|
||||
def __init__(self):
|
||||
rd = bpy.context.scene.render
|
||||
im = rd.image_settings
|
||||
ff = rd.ffmpeg
|
||||
# ffmpeg (ff) need to be before image_settings(im) in list
|
||||
# otherwise __exit__ may try to restore settings of image mode in video mode !
|
||||
# ex : "RGBA" not found in ('BW', 'RGB') (will still not stop thx to try block)
|
||||
self.zones = [rd, ff, im]
|
||||
|
||||
self.val_dic = {}
|
||||
self.cam = bpy.context.scene.camera
|
||||
|
||||
def __enter__(self):
|
||||
## store attribute of data_path in self.zones list.
|
||||
for data_path in self.zones:
|
||||
self.val_dic[data_path] = {}
|
||||
for attr in dir(data_path):#iterate in attribute of given datapath
|
||||
if attr not in exclude and not attr.startswith('__') and not callable(getattr(data_path, attr)) and not data_path.is_property_readonly(attr):
|
||||
self.val_dic[data_path][attr] = getattr(data_path, attr)
|
||||
|
||||
if self.cam and self.cam.name == 'draw_cam':
|
||||
if self.cam.parent:
|
||||
bpy.context.scene.camera = self.cam.parent
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
## restore attribute from self.zones list
|
||||
for data_path, prop_dic in self.val_dic.items():
|
||||
for attr, val in prop_dic.items():
|
||||
try:
|
||||
setattr(data_path, attr, val)
|
||||
except Exception as e:
|
||||
print(f"/!\ Impossible to re-assign: {attr} = {val}")
|
||||
print(e)
|
||||
|
||||
if self.cam:
|
||||
bpy.context.scene.camera = self.cam
|
||||
|
||||
def playblast(viewport = False, stamping = True):
|
||||
scn = bpy.context.scene
|
||||
res_factor = scn.gptoolprops.resolution_percentage
|
||||
|
@ -91,15 +132,15 @@ def playblast(viewport = False, stamping = True):
|
|||
### can add propeties for personalisation as toolsetting props
|
||||
|
||||
rd.resolution_percentage = res_factor
|
||||
while ( rd.resolution_x * res_factor / 100 ) % 2 != 0:# rd.resolution_percentage
|
||||
while ( rd.resolution_x * res_factor / 100 ) % 2 != 0: # rd.resolution_percentage
|
||||
rd.resolution_x = rd.resolution_x + 1
|
||||
while ( rd.resolution_y * res_factor / 100 ) % 2 != 0:# rd.resolution_percentage
|
||||
rd.resolution_y = rd.resolution_y + 1
|
||||
while ( rd.resolution_y * res_factor / 100 ) % 2 != 0: # rd.resolution_percentage
|
||||
rd.resolution_y = rd.resolution_y + 1
|
||||
|
||||
rd.image_settings.file_format = 'FFMPEG'
|
||||
ff.format = 'MPEG4'
|
||||
ff.codec = 'H264'
|
||||
ff.constant_rate_factor = 'HIGH'# MEDIUM
|
||||
ff.constant_rate_factor = 'HIGH' # MEDIUM
|
||||
ff.ffmpeg_preset = 'REALTIME'
|
||||
ff.gopsize = 10
|
||||
ff.audio_codec = 'AAC'
|
||||
|
@ -116,13 +157,13 @@ def playblast(viewport = False, stamping = True):
|
|||
# mode incermental or just use fulldate (cannot create conflict and filter OK but long name)
|
||||
blend = Path(bpy.data.filepath)
|
||||
date_format = "%Y-%m-%d_%H-%M-%S"
|
||||
fp = join(blend.parent, "images", f'playblast_{blend.stem}_{strftime(date_format)}.mp4')
|
||||
fp = join(blend.parent, "playblast", f'playblast_{blend.stem}_{strftime(date_format)}.mp4')
|
||||
|
||||
#may need a properties for choosing location : bpy.types.Scene.qrd_savepath = bpy.props.StringProperty(subtype='DIR_PATH', description="Export location, if not specify, create a 'quick_render' directory aside blend location")#(change defaut name in user_prefernece)
|
||||
rd.filepath = fp
|
||||
rd.use_stamp = stamping# toolsetting.use_stamp# True for playblast
|
||||
#stamp options
|
||||
rd.stamp_font_size = rd.stamp_font_size * res_factor / 100# rd.resolution_percentage
|
||||
rd.stamp_font_size = int(rd.stamp_font_size * res_factor / 100) # rd.resolution_percentage
|
||||
|
||||
# bpy.ops.render.render_wrap(use_view=viewport)
|
||||
### render
|
||||
|
|
|
@ -21,15 +21,20 @@ exclude = (
|
|||
'bl_rna', 'identifier','name_property','rna_type','properties', 'compare', 'to_string',#basic
|
||||
)
|
||||
|
||||
def delete_file(filepath) :
|
||||
try:
|
||||
if os.path.isfile(filepath) :
|
||||
print('removing', filepath)
|
||||
os.remove(filepath)
|
||||
def delete_file(filepath):
|
||||
fp = Path(filepath)
|
||||
if fp.exists() and fp.is_file():
|
||||
try:
|
||||
print('removing', fp)
|
||||
fp.unlink(missing_ok=False)
|
||||
# os.remove(fp)
|
||||
return True
|
||||
except PermissionError:
|
||||
print(f'impossible to remove {filepath}')
|
||||
return False
|
||||
except PermissionError:
|
||||
print(f'impossible to remove (permission error): {fp}')
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
print(f'Impossible to remove (file not found error): {fp}')
|
||||
return False
|
||||
|
||||
# render function
|
||||
def render_function(cmd, total_frame, scene) :
|
||||
|
@ -58,7 +63,7 @@ def render_function(cmd, total_frame, scene) :
|
|||
frame_count += 1
|
||||
try :
|
||||
# print('frame_count: ', frame_count, 'total_frame: ', total_frame)
|
||||
bpy.context.window_manager.pblast_completion = frame_count / total_frame * 100
|
||||
bpy.context.window_manager.pblast_completion = int(frame_count / total_frame * 100)
|
||||
except AttributeError :
|
||||
#debug
|
||||
if debug : print("AttributeError avoided")
|
||||
|
@ -231,9 +236,7 @@ class BGBLAST_OT_playblast_modal_check(bpy.types.Operator):
|
|||
|
||||
self.report({'INFO'}, "Render Finished")
|
||||
|
||||
|
||||
### classic sauce
|
||||
|
||||
"""
|
||||
def render_with_restore():
|
||||
class RenderFileRestorer:
|
||||
rd = bpy.context.scene.render
|
||||
|
@ -266,6 +269,38 @@ def render_with_restore():
|
|||
print(e)
|
||||
|
||||
return RenderFileRestorer()
|
||||
"""
|
||||
|
||||
class render_with_restore:
|
||||
def __init__(self):
|
||||
rd = bpy.context.scene.render
|
||||
im = rd.image_settings
|
||||
ff = rd.ffmpeg
|
||||
# ffmpeg (ff) need to be before image_settings(im) in list
|
||||
# otherwise __exit__ may try to restore settings of image mode in video mode !
|
||||
# ex : "RGBA" not found in ('BW', 'RGB') (will still not stop thx to try block)
|
||||
|
||||
self.zones = [rd, ff, im]
|
||||
|
||||
self.val_dic = {}
|
||||
|
||||
def __enter__(self):
|
||||
## store attribute of data_path in self.zones list.
|
||||
for data_path in self.zones:
|
||||
self.val_dic[data_path] = {}
|
||||
for attr in dir(data_path):#iterate in attribute of given datapath
|
||||
if attr not in exclude and not attr.startswith('__') and not callable(getattr(data_path, attr)) and not data_path.is_property_readonly(attr):
|
||||
self.val_dic[data_path][attr] = getattr(data_path, attr)
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
## restore attribute from self.zones list
|
||||
for data_path, prop_dic in self.val_dic.items():
|
||||
for attr, val in prop_dic.items():
|
||||
try:
|
||||
setattr(data_path, attr, val)
|
||||
except Exception as e:
|
||||
print(f"/!\ Impossible to re-assign: {attr} = {val}")
|
||||
print(e)
|
||||
|
||||
|
||||
def playblast(context, viewport = False, stamping = True):
|
||||
|
@ -325,7 +360,7 @@ def playblast(context, viewport = False, stamping = True):
|
|||
rd.filepath = fp
|
||||
rd.use_stamp = stamping# toolsetting.use_stamp# True for playblast
|
||||
#stamp options
|
||||
rd.stamp_font_size = rd.stamp_font_size * res_factor / 100# rd.resolution_percentage
|
||||
rd.stamp_font_size = int(rd.stamp_font_size * res_factor / 100) # rd.resolution_percentage
|
||||
|
||||
|
||||
# get total number of frames
|
||||
|
|
19
__init__.py
19
__init__.py
|
@ -1,21 +1,10 @@
|
|||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
bl_info = {
|
||||
"name": "GP toolbox",
|
||||
"description": "Tool set for Grease Pencil in animation production",
|
||||
"author": "Samuel Bernou, Christophe Seux",
|
||||
"version": (1, 9, 9),
|
||||
"version": (2, 0, 0),
|
||||
"blender": (2, 91, 0),
|
||||
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||
"warning": "",
|
||||
|
@ -24,14 +13,10 @@ bl_info = {
|
|||
"category": "3D View",
|
||||
}
|
||||
|
||||
# from . import addon_updater_ops
|
||||
|
||||
# from .utils import *
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
from sys import modules
|
||||
from .utils import get_addon_prefs, draw_kmi
|
||||
# from .functions import *
|
||||
|
||||
## GMIC
|
||||
from .GP_guided_colorize import GP_colorize
|
||||
|
|
Loading…
Reference in New Issue