Flamenco: Reporting BAT Pack process on the UI
This commit is contained in:
parent
9e5dcd0b55
commit
b82bc14fcf
@ -170,7 +170,7 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
|
||||
scene = context.scene
|
||||
|
||||
# Save to a different file, specifically for Flamenco.
|
||||
context.window_manager.flamenco_status = 'PACKING'
|
||||
context.window_manager.flamenco_status = 'SAVING'
|
||||
filepath = await self._save_blendfile(context)
|
||||
|
||||
# Determine where the render output will be stored.
|
||||
@ -348,7 +348,7 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
|
||||
|
||||
try:
|
||||
outfile, missing_sources = await bat_interface.bat_copy(
|
||||
filepath, projdir, outdir, exclusion_filter)
|
||||
bpy.context, filepath, projdir, outdir, exclusion_filter)
|
||||
except bat_interface.FileTransferError as ex:
|
||||
self.log.error('Could not transfer %d files, starting with %s',
|
||||
len(ex.files_remaining), ex.files_remaining[0])
|
||||
@ -380,7 +380,10 @@ class FLAMENCO_OT_scene_to_frame_range(FlamencoPollMixin, Operator):
|
||||
class FLAMENCO_OT_copy_files(Operator,
|
||||
FlamencoPollMixin,
|
||||
async_loop.AsyncModalOperatorMixin):
|
||||
"""Uses BAT to copy the current blendfile + dependencies to the target directory."""
|
||||
"""Uses BAT to copy the current blendfile + dependencies to the target directory.
|
||||
|
||||
This operator is not used directly, but can be useful for testing.
|
||||
"""
|
||||
bl_idname = 'flamenco.copy_files'
|
||||
bl_label = 'Copy files to target'
|
||||
bl_description = __doc__.rstrip('.')
|
||||
@ -395,7 +398,8 @@ class FLAMENCO_OT_copy_files(Operator,
|
||||
prefs = preferences()
|
||||
exclusion_filter = (prefs.flamenco_exclude_filter or '').strip()
|
||||
|
||||
missing_sources = await bat_interface.bat_copy(
|
||||
outpath, missing_sources = await bat_interface.bat_copy(
|
||||
context,
|
||||
Path(context.blend_data.filepath),
|
||||
Path(prefs.cloud_project_local_path),
|
||||
Path(prefs.flamenco_job_file_path),
|
||||
@ -405,7 +409,8 @@ class FLAMENCO_OT_copy_files(Operator,
|
||||
if missing_sources:
|
||||
names = (ms.name for ms in missing_sources)
|
||||
self.report({'ERROR'}, 'Missing source files: %s' % '; '.join(names))
|
||||
|
||||
else:
|
||||
self.report({'INFO'}, 'Written %s' % outpath)
|
||||
self.quit()
|
||||
|
||||
def quit(self):
|
||||
@ -684,12 +689,16 @@ class FLAMENCO_PT_render(bpy.types.Panel, FlamencoPollMixin):
|
||||
layout.operator(FLAMENCO_OT_render.bl_idname,
|
||||
text='Render on Flamenco',
|
||||
icon='RENDER_ANIMATION')
|
||||
elif flamenco_status == 'PACKING':
|
||||
layout.label('Flamenco is packing your file + dependencies')
|
||||
elif flamenco_status == 'INVESTIGATING':
|
||||
layout.label('Investigating your files')
|
||||
elif flamenco_status == 'COMMUNICATING':
|
||||
layout.label('Communicating with Flamenco Server')
|
||||
else:
|
||||
layout.label('Unknown Flamenco status %s' % flamenco_status)
|
||||
|
||||
if flamenco_status == 'TRANSFERRING':
|
||||
layout.prop(context.window_manager, 'flamenco_progress',
|
||||
text=context.window_manager.flamenco_status_txt)
|
||||
elif flamenco_status != 'IDLE':
|
||||
layout.label(context.window_manager.flamenco_status_txt)
|
||||
|
||||
|
||||
def activate():
|
||||
@ -790,14 +799,32 @@ def register():
|
||||
bpy.types.WindowManager.flamenco_status = EnumProperty(
|
||||
items=[
|
||||
('IDLE', 'IDLE', 'Not doing anything.'),
|
||||
('PACKING', 'PACKING', 'BAT-packing all dependencies.'),
|
||||
('SAVING', 'SAVING', 'Saving your file.'),
|
||||
('INVESTIGATING', 'INVESTIGATING', 'Finding all dependencies.'),
|
||||
('TRANSFERRING', 'TRANSFERRING', 'Transferring all dependencies.'),
|
||||
('COMMUNICATING', 'COMMUNICATING', 'Communicating with Flamenco Server.'),
|
||||
('DONE', 'DONE', 'Not doing anything, but doing something earlier.'),
|
||||
],
|
||||
name='flamenco_status',
|
||||
default='IDLE',
|
||||
description='Current status of the Flamenco add-on',
|
||||
update=redraw)
|
||||
|
||||
bpy.types.WindowManager.flamenco_status_txt = StringProperty(
|
||||
name='Flamenco Status',
|
||||
default='',
|
||||
description='Textual description of what Flamenco is doing',
|
||||
update=redraw)
|
||||
|
||||
bpy.types.WindowManager.flamenco_progress = IntProperty(
|
||||
name='Flamenco Progress',
|
||||
default=0,
|
||||
description='File transfer progress',
|
||||
subtype='PERCENTAGE',
|
||||
min=0,
|
||||
max=100,
|
||||
update=redraw)
|
||||
|
||||
|
||||
def unregister():
|
||||
deactivate()
|
||||
|
@ -3,18 +3,79 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import typing
|
||||
from pathlib import Path
|
||||
import pathlib
|
||||
|
||||
from blender_asset_tracer import pack
|
||||
from blender_asset_tracer.pack import progress
|
||||
|
||||
from blender_asset_tracer.pack.transfer import FileTransferError
|
||||
|
||||
import bpy
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def bat_copy(base_blendfile: Path,
|
||||
project: Path,
|
||||
target: Path,
|
||||
exclusion_filter: str) -> typing.Tuple[Path, typing.Set[Path]]:
|
||||
class BatProgress(progress.Callback):
|
||||
"""Report progress of BAT Packing to the UI.
|
||||
|
||||
Uses asyncio.run_coroutine_threadsafe() to ensure the UI is only updated
|
||||
from the main thread. This is required since we run the BAT Pack in a
|
||||
background thread.
|
||||
"""
|
||||
|
||||
def __init__(self, context) -> None:
|
||||
super().__init__()
|
||||
self.wm = context.window_manager
|
||||
self.loop = asyncio.get_event_loop()
|
||||
|
||||
def txt(self, msg: str):
|
||||
"""Set a text in a thread-safe way."""
|
||||
async def set_text():
|
||||
self.wm.flamenco_status_txt = msg
|
||||
asyncio.run_coroutine_threadsafe(set_text(), loop=self.loop)
|
||||
|
||||
def pack_start(self) -> None:
|
||||
self.txt('Starting BAT Pack operation')
|
||||
|
||||
def pack_done(self,
|
||||
output_blendfile: pathlib.Path,
|
||||
missing_files: typing.Set[pathlib.Path]) -> None:
|
||||
if missing_files:
|
||||
self.txt('There were %d missing files' % len(missing_files))
|
||||
else:
|
||||
self.txt('Pack of %s done' % output_blendfile.name)
|
||||
|
||||
def trace_blendfile(self, filename: pathlib.Path) -> None:
|
||||
"""Called for every blendfile opened when tracing dependencies."""
|
||||
self.txt('Inspecting %s' % filename.name)
|
||||
|
||||
def trace_asset(self, filename: pathlib.Path) -> None:
|
||||
if filename.stem == '.blend':
|
||||
return
|
||||
self.txt('Found asset %s' % filename.name)
|
||||
|
||||
def rewrite_blendfile(self, orig_filename: pathlib.Path) -> None:
|
||||
self.txt('Rewriting %s' % orig_filename.name)
|
||||
|
||||
def transfer_file(self, src: pathlib.Path, dst: pathlib.Path) -> None:
|
||||
self.txt('Transferring %s' % src.name)
|
||||
|
||||
def transfer_file_skipped(self, src: pathlib.Path, dst: pathlib.Path) -> None:
|
||||
self.txt('Skipped %s' % src.name)
|
||||
|
||||
def transfer_progress(self, total_bytes: int, transferred_bytes: int) -> None:
|
||||
self.wm.flamenco_progress = 100 * transferred_bytes / total_bytes
|
||||
|
||||
def missing_file(self, filename: pathlib.Path) -> None:
|
||||
# TODO(Sybren): report missing files in a nice way
|
||||
pass
|
||||
|
||||
|
||||
async def bat_copy(context,
|
||||
base_blendfile: pathlib.Path,
|
||||
project: pathlib.Path,
|
||||
target: pathlib.Path,
|
||||
exclusion_filter: str) -> typing.Tuple[pathlib.Path, typing.Set[pathlib.Path]]:
|
||||
"""Use BAT🦇 to copy the given file and dependencies to the target location.
|
||||
|
||||
:raises: FileTransferError if a file couldn't be transferred.
|
||||
@ -23,13 +84,23 @@ async def bat_copy(base_blendfile: Path,
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
with pack.Packer(base_blendfile, project, target) as packer:
|
||||
if exclusion_filter:
|
||||
packer.exclude(*exclusion_filter.split())
|
||||
|
||||
packer.progress_cb = BatProgress(context)
|
||||
|
||||
log.debug('awaiting strategise')
|
||||
wm.flamenco_status = 'INVESTIGATING'
|
||||
await loop.run_in_executor(None, packer.strategise)
|
||||
|
||||
log.debug('awaiting execute')
|
||||
wm.flamenco_status = 'TRANSFERRING'
|
||||
await loop.run_in_executor(None, packer.execute)
|
||||
|
||||
log.debug('done')
|
||||
wm.flamenco_status = 'DONE'
|
||||
|
||||
return packer.output_path, packer.missing_files
|
||||
|
@ -99,4 +99,6 @@ def pyside_cache(propname):
|
||||
|
||||
|
||||
def redraw(self, context):
|
||||
if context.area is None:
|
||||
return
|
||||
context.area.tag_redraw()
|
||||
|
Reference in New Issue
Block a user