Compare commits

..

19 Commits

Author SHA1 Message Date
5b77ae50a1 Bumped version to 1.6.1 2017-03-07 11:01:11 +01:00
74958cf217 Show error in GUI when Blender Cloud is unreachable 2017-03-07 11:00:42 +01:00
5026dfc441 Fixed sample count when using branched path tracing
Thanks to dr. Sharybin for the patch.
2017-03-07 11:00:23 +01:00
843667e612 Bumped version to 1.6.0 2017-02-14 10:22:35 +01:00
cf3f7234eb Default to frame chunk size of 1 (instead of 10) 2017-02-14 10:22:06 +01:00
4647175a7e Turn off "use overwrite" and "use placeholder" for Flamenco blend files.
If you want to re-render frames, delete them first, then reschedule
the render task.
2017-02-14 10:21:50 +01:00
33da5195f3 Fixed bugs when blendfile is outside the project directory 2017-02-01 14:00:46 +01:00
3814fb2683 Bumped version to 1.5.999999 2017-02-01 09:57:49 +01:00
15484a65cd Tweaked output dir to not end in '.flamenco' 2017-01-31 18:29:10 +01:00
d9e2b36204 A bit broader exception handling 2017-01-31 18:29:00 +01:00
cc690ec8c9 Always use EXR for progressive rendering 2017-01-31 18:28:47 +01:00
0422070d55 Flamenco: use 6 #-signs, Flamenco Server expects this 2017-01-31 18:28:35 +01:00
8cefb4fb07 Flamenco: Take "Square samples" into account when computing nr of samples 2017-01-31 18:28:14 +01:00
23549fa676 Added support for blender-render-progressive jobs 2017-01-30 10:38:35 +01:00
cb73030e6a Bumped version to 1.5.99999 2017-01-24 17:22:04 +01:00
fbf02c3625 Captialising labels/captions 2017-01-24 15:15:08 +01:00
95699aca36 Open webbrowser after submitting a Flamenco job
This can be disabled in the add-on preferences.
2017-01-24 15:14:43 +01:00
60018cd78c Using explicit status EnumProperty to show Flamenco status
By Andy's request, I've removed the window_manager.progress_xxx stuff (so
no longer hijacking the mouse cursor) and instead show the Flamenco status
in the Flamenco Render panel.
2017-01-24 14:55:39 +01:00
5f73837d3c Don't write to artist's blend file, but to temporary file.
This file is saved to '{blendfile}.flamenco.blend', which is used to BAM-
pack and create the Flamenco job. After that, the file is removed from
the local filesystem again.
2017-01-24 14:39:49 +01:00
5 changed files with 205 additions and 62 deletions

View File

@@ -21,7 +21,7 @@
bl_info = { bl_info = {
'name': 'Blender Cloud', 'name': 'Blender Cloud',
"author": "Sybren A. Stüvel, Francesco Siddi, Inês Almeida, Antony Riakiotakis", "author": "Sybren A. Stüvel, Francesco Siddi, Inês Almeida, Antony Riakiotakis",
'version': (1, 5, 9999), 'version': (1, 6, 1),
'blender': (2, 77, 0), 'blender': (2, 77, 0),
'location': 'Addon Preferences panel, and Ctrl+Shift+Alt+A anywhere for texture browser', 'location': 'Addon Preferences panel, and Ctrl+Shift+Alt+A anywhere for texture browser',
'description': 'Texture library browser and Blender Sync. Requires the Blender ID addon ' 'description': 'Texture library browser and Blender Sync. Requires the Blender ID addon '

View File

@@ -155,12 +155,12 @@ class BlenderCloudPreferences(AddonPreferences):
) )
local_texture_dir = StringProperty( local_texture_dir = StringProperty(
name='Default Blender Cloud texture storage directory', name='Default Blender Cloud Texture Storage Directory',
subtype='DIR_PATH', subtype='DIR_PATH',
default='//textures') default='//textures')
open_browser_after_share = BoolProperty( open_browser_after_share = BoolProperty(
name='Open browser after sharing file', name='Open Browser after Sharing File',
description='When enabled, Blender will open a webbrowser', description='When enabled, Blender will open a webbrowser',
default=True default=True
) )
@@ -169,7 +169,7 @@ class BlenderCloudPreferences(AddonPreferences):
# can switch projects and the local path switches with it. # can switch projects and the local path switches with it.
attract_project = PointerProperty(type=BlenderCloudProjectGroup) attract_project = PointerProperty(type=BlenderCloudProjectGroup)
attract_project_local_path = StringProperty( attract_project_local_path = StringProperty(
name='Local project path', name='Local Project Path',
description='Local path of your Attract project, used to search for blend files; ' description='Local path of your Attract project, used to search for blend files; '
'usually best to set to an absolute path', 'usually best to set to an absolute path',
subtype='DIR_PATH', subtype='DIR_PATH',
@@ -180,19 +180,19 @@ class BlenderCloudPreferences(AddonPreferences):
# NOTE: The assumption is that the workers can also find the files in the same path. # NOTE: The assumption is that the workers can also find the files in the same path.
# This assumption is true for the Blender Institute. # This assumption is true for the Blender Institute.
flamenco_job_file_path = StringProperty( flamenco_job_file_path = StringProperty(
name='Job file path', name='Job File Path',
description='Path where to store job files, should be accesible for Workers too', description='Path where to store job files, should be accesible for Workers too',
subtype='DIR_PATH', subtype='DIR_PATH',
default='/render/_flamenco/storage') default='/render/_flamenco/storage')
# TODO: before making Flamenco public, change the defaults to something less Institute-specific. # TODO: before making Flamenco public, change the defaults to something less Institute-specific.
flamenco_job_output_path = StringProperty( flamenco_job_output_path = StringProperty(
name='Job output path', name='Job Output Path',
description='Path where to store output files, should be accessible for Workers', description='Path where to store output files, should be accessible for Workers',
subtype='DIR_PATH', subtype='DIR_PATH',
default='/render/_flamenco/output') default='/render/_flamenco/output')
flamenco_job_output_strip_components = IntProperty( flamenco_job_output_strip_components = IntProperty(
name='Job output path strip components', name='Job Output Path Strip Components',
description='The final output path comprises of the job output path, and the blend file ' description='The final output path comprises of the job output path, and the blend file '
'path relative to the project with this many path components stripped off ' 'path relative to the project with this many path components stripped off '
'the front', 'the front',
@@ -200,6 +200,11 @@ class BlenderCloudPreferences(AddonPreferences):
default=0, default=0,
soft_max=4, soft_max=4,
) )
flamenco_open_browser_after_submit = BoolProperty(
name='Open Browser after Submitting Job',
description='When enabled, Blender will open a webbrowser',
default=True
)
def draw(self, context): def draw(self, context):
import textwrap import textwrap
@@ -379,15 +384,21 @@ class BlenderCloudPreferences(AddonPreferences):
props.path = self.flamenco_job_output_path props.path = self.flamenco_job_output_path
job_output_box.prop(self, 'flamenco_job_output_strip_components', job_output_box.prop(self, 'flamenco_job_output_strip_components',
text='Strip components') text='Strip Components')
from .flamenco import render_output_path from .flamenco import render_output_path
path_box = job_output_box.row(align=True) path_box = job_output_box.row(align=True)
output_path = render_output_path(context) output_path = render_output_path(context)
path_box.label(str(output_path)) if output_path:
props = path_box.operator('flamenco.explore_file_path', text='', icon='DISK_DRIVE') path_box.label(str(output_path))
props.path = str(output_path.parent) props = path_box.operator('flamenco.explore_file_path', text='', icon='DISK_DRIVE')
props.path = str(output_path.parent)
else:
path_box.label('Blend file is not in your project path, '
'unable to give output path example.')
flamenco_box.prop(self, 'flamenco_open_browser_after_submit')
# TODO: make a reusable way to select projects, and use that for Attract and Flamenco. # TODO: make a reusable way to select projects, and use that for Attract and Flamenco.
note_box = flamenco_box.column(align=True) note_box = flamenco_box.column(align=True)

View File

@@ -128,22 +128,16 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
if not await self.authenticate(context): if not await self.authenticate(context):
return return
context.window_manager.progress_begin(0, 4)
context.window_manager.progress_update(1)
from pillarsdk import exceptions as sdk_exceptions
from ..blender import preferences from ..blender import preferences
filepath = Path(context.blend_data.filepath)
scene = context.scene scene = context.scene
# The file extension should be determined by the render settings, not necessarily # Save to a different file, specifically for Flamenco.
# by the setttings in the output panel. context.window_manager.flamenco_status = 'PACKING'
scene.render.use_file_extension = True filepath = await self._save_blendfile(context)
bpy.ops.wm.save_mainfile()
# Determine where the render output will be stored. # Determine where the render output will be stored.
render_output = render_output_path(context) render_output = render_output_path(context, filepath)
if render_output is None: if render_output is None:
self.report({'ERROR'}, 'Current file is outside of project path.') self.report({'ERROR'}, 'Current file is outside of project path.')
self.quit() self.quit()
@@ -155,17 +149,31 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
if not outfile: if not outfile:
return return
context.window_manager.progress_update(3)
# Create the job at Flamenco Server. # Create the job at Flamenco Server.
prefs = preferences() prefs = preferences()
context.window_manager.flamenco_status = 'COMMUNICATING'
settings = {'blender_cmd': '{blender}', settings = {'blender_cmd': '{blender}',
'chunk_size': scene.flamenco_render_chunk_size, 'chunk_size': scene.flamenco_render_fchunk_size,
'filepath': str(outfile), 'filepath': str(outfile),
'frames': scene.flamenco_render_frame_range, 'frames': scene.flamenco_render_frame_range,
'render_output': str(render_output), 'render_output': str(render_output),
} }
# Add extra settings specific to the job type
if scene.flamenco_render_job_type == 'blender-render-progressive':
if scene.cycles.progressive == 'BRANCHED_PATH':
samples = scene.cycles.aa_samples
else:
samples = scene.cycles.samples
if scene.cycles.use_square_samples:
samples **= 2
settings['cycles_num_chunks'] = scene.flamenco_render_schunk_count
settings['cycles_sample_count'] = samples
settings['format'] = 'EXR'
try: try:
job_info = await create_job(self.user_id, job_info = await create_job(self.user_id,
prefs.attract_project.project, prefs.attract_project.project,
@@ -174,7 +182,7 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
settings, settings,
'Render %s' % filepath.name, 'Render %s' % filepath.name,
priority=scene.flamenco_render_job_priority) priority=scene.flamenco_render_job_priority)
except sdk_exceptions.ResourceInvalid as ex: except Exception as ex:
self.report({'ERROR'}, 'Error creating Flamenco job: %s' % ex) self.report({'ERROR'}, 'Error creating Flamenco job: %s' % ex)
self.quit() self.quit()
return return
@@ -186,6 +194,25 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
job_info['missing_files'] = [str(mf) for mf in missing_sources] job_info['missing_files'] = [str(mf) for mf in missing_sources]
json.dump(job_info, outfile, sort_keys=True, indent=4) json.dump(job_info, outfile, sort_keys=True, indent=4)
# We can now remove the local copy we made with bpy.ops.wm.save_as_mainfile().
# Strictly speaking we can already remove it after the BAM-pack, but it may come in
# handy in case of failures.
try:
self.log.info('Removing temporary file %s', filepath)
filepath.unlink()
except Exception as ex:
self.report({'ERROR'}, 'Unable to remove file: %s' % ex)
self.quit()
return
if prefs.flamenco_open_browser_after_submit:
import webbrowser
from urllib.parse import urljoin
from ..blender import PILLAR_WEB_SERVER_URL
url = urljoin(PILLAR_WEB_SERVER_URL, '/flamenco/jobs/%s/redir' % job_info['_id'])
webbrowser.open_new_tab(url)
# Do a final report. # Do a final report.
if missing_sources: if missing_sources:
names = (ms.name for ms in missing_sources) names = (ms.name for ms in missing_sources)
@@ -193,11 +220,49 @@ class FLAMENCO_OT_render(async_loop.AsyncModalOperatorMixin,
'; '.join(names)) '; '.join(names))
else: else:
self.report({'INFO'}, 'Flamenco job created.') self.report({'INFO'}, 'Flamenco job created.')
self.quit() self.quit()
async def _save_blendfile(self, context):
"""Save to a different file, specifically for Flamenco.
We shouldn't overwrite the artist's file.
We can compress, since this file won't be managed by SVN and doesn't need diffability.
"""
render = context.scene.render
# Remember settings we need to restore after saving.
old_use_file_extension = render.use_file_extension
old_use_overwrite = render.use_overwrite
old_use_placeholder = render.use_placeholder
try:
# The file extension should be determined by the render settings, not necessarily
# by the setttings in the output panel.
render.use_file_extension = True
# Rescheduling should not overwrite existing frames.
render.use_overwrite = False
render.use_placeholder = False
filepath = Path(context.blend_data.filepath).with_suffix('.flamenco.blend')
self.log.info('Saving copy to temporary file %s', filepath)
bpy.ops.wm.save_as_mainfile(filepath=str(filepath),
compress=True,
copy=True)
finally:
# Restore the settings we changed, even after an exception.
render.use_file_extension = old_use_file_extension
render.use_overwrite = old_use_overwrite
render.use_placeholder = old_use_placeholder
return filepath
def quit(self): def quit(self):
super().quit() super().quit()
bpy.context.window_manager.progress_end() bpy.context.window_manager.flamenco_status = 'IDLE'
async def bam_pack(self, filepath: Path) -> (typing.Optional[Path], typing.List[Path]): async def bam_pack(self, filepath: Path) -> (typing.Optional[Path], typing.List[Path]):
"""BAM-packs the blendfile to the destination directory. """BAM-packs the blendfile to the destination directory.
@@ -269,6 +334,8 @@ class FLAMENCO_OT_copy_files(Operator,
from . import bam_interface from . import bam_interface
from ..blender import preferences from ..blender import preferences
context.window_manager.flamenco_status = 'PACKING'
missing_sources = await bam_interface.bam_copy( missing_sources = await bam_interface.bam_copy(
Path(context.blend_data.filepath), Path(context.blend_data.filepath),
Path(preferences().flamenco_job_file_path), Path(preferences().flamenco_job_file_path),
@@ -280,6 +347,10 @@ class FLAMENCO_OT_copy_files(Operator,
self.quit() self.quit()
def quit(self):
super().quit()
bpy.context.window_manager.flamenco_status = 'IDLE'
class FLAMENCO_OT_explore_file_path(Operator): class FLAMENCO_OT_explore_file_path(Operator):
"""Opens the Flamenco job storage path in a file explorer.""" """Opens the Flamenco job storage path in a file explorer."""
@@ -353,7 +424,7 @@ def is_image_type(render_output_type: str) -> bool:
@functools.lru_cache(1) @functools.lru_cache(1)
def _render_output_path( def _render_output_path(
local_project_path: str, local_project_path: str,
blend_filepath: str, blend_filepath: Path,
flamenco_job_output_strip_components: int, flamenco_job_output_strip_components: int,
flamenco_job_output_path: str, flamenco_job_output_path: str,
render_image_format: str, render_image_format: str,
@@ -365,27 +436,40 @@ def _render_output_path(
is fast. is fast.
""" """
project_path = Path(bpy.path.abspath(local_project_path)).resolve() try:
blendfile = Path(blend_filepath) project_path = Path(bpy.path.abspath(local_project_path)).resolve()
except FileNotFoundError:
# Path.resolve() will raise a FileNotFoundError if the project path doesn't exist.
return None
try: try:
proj_rel = blendfile.parent.relative_to(project_path) proj_rel = blend_filepath.parent.relative_to(project_path)
except ValueError: except ValueError:
return None return None
rel_parts = proj_rel.parts[flamenco_job_output_strip_components:] rel_parts = proj_rel.parts[flamenco_job_output_strip_components:]
output_top = Path(flamenco_job_output_path) output_top = Path(flamenco_job_output_path)
dir_components = output_top.joinpath(*rel_parts) / blendfile.stem
# Strip off '.flamenco' too; we use 'xxx.flamenco.blend' as job file, but
# don't want to have all the output paths ending in '.flamenco'.
stem = blend_filepath.stem
if stem.endswith('.flamenco'):
stem = stem[:-9]
dir_components = output_top.joinpath(*rel_parts) / stem
# Blender will have to append the file extensions by itself. # Blender will have to append the file extensions by itself.
if is_image_type(render_image_format): if is_image_type(render_image_format):
return dir_components / '#####' return dir_components / '######'
return dir_components / flamenco_render_frame_range return dir_components / flamenco_render_frame_range
def render_output_path(context) -> typing.Optional[PurePath]: def render_output_path(context, filepath: Path = None) -> typing.Optional[PurePath]:
"""Returns the render output path to be sent to Flamenco. """Returns the render output path to be sent to Flamenco.
:param context: the Blender context (used to find Flamenco preferences etc.)
:param filepath: the Path of the blend file to render, or None for the current file.
Returns None when the current blend file is outside the project path. Returns None when the current blend file is outside the project path.
""" """
@@ -394,9 +478,12 @@ def render_output_path(context) -> typing.Optional[PurePath]:
scene = context.scene scene = context.scene
prefs = preferences() prefs = preferences()
if filepath is None:
filepath = Path(context.blend_data.filepath)
return _render_output_path( return _render_output_path(
prefs.attract_project_local_path, prefs.attract_project_local_path,
context.blend_data.filepath, filepath,
prefs.flamenco_job_output_strip_components, prefs.flamenco_job_output_strip_components,
prefs.flamenco_job_output_path, prefs.flamenco_job_output_path,
scene.render.image_settings.file_format, scene.render.image_settings.file_format,
@@ -418,21 +505,24 @@ class FLAMENCO_PT_render(bpy.types.Panel):
prefs = preferences() prefs = preferences()
layout.prop(context.scene, 'flamenco_render_job_priority') labeled_row = layout.split(0.25, align=True)
layout.prop(context.scene, 'flamenco_render_chunk_size') labeled_row.label('Job Type:')
labeled_row = layout.split(0.2, align=True)
labeled_row.label('Job type:')
labeled_row.prop(context.scene, 'flamenco_render_job_type', text='') labeled_row.prop(context.scene, 'flamenco_render_job_type', text='')
labeled_row = layout.split(0.2, align=True) labeled_row = layout.split(0.25, align=True)
labeled_row.label('Frame range:') labeled_row.label('Frame Range:')
prop_btn_row = labeled_row.row(align=True) prop_btn_row = labeled_row.row(align=True)
prop_btn_row.prop(context.scene, 'flamenco_render_frame_range', text='') prop_btn_row.prop(context.scene, 'flamenco_render_frame_range', text='')
prop_btn_row.operator('flamenco.scene_to_frame_range', text='', icon='ARROW_LEFTRIGHT') prop_btn_row.operator('flamenco.scene_to_frame_range', text='', icon='ARROW_LEFTRIGHT')
layout.prop(context.scene, 'flamenco_render_job_priority')
layout.prop(context.scene, 'flamenco_render_fchunk_size')
if getattr(context.scene, 'flamenco_render_job_type', None) == 'blender-render-progressive':
layout.prop(context.scene, 'flamenco_render_schunk_count')
readonly_stuff = layout.column(align=True) readonly_stuff = layout.column(align=True)
labeled_row = readonly_stuff.split(0.2, align=True) labeled_row = readonly_stuff.split(0.25, align=True)
labeled_row.label('Storage:') labeled_row.label('Storage:')
prop_btn_row = labeled_row.row(align=True) prop_btn_row = labeled_row.row(align=True)
prop_btn_row.label(prefs.flamenco_job_file_path) prop_btn_row.label(prefs.flamenco_job_file_path)
@@ -440,10 +530,11 @@ class FLAMENCO_PT_render(bpy.types.Panel):
text='', icon='DISK_DRIVE') text='', icon='DISK_DRIVE')
props.path = prefs.flamenco_job_file_path props.path = prefs.flamenco_job_file_path
labeled_row = readonly_stuff.split(0.2, align=True) labeled_row = readonly_stuff.split(0.25, align=True)
labeled_row.label('Output:') labeled_row.label('Output:')
prop_btn_row = labeled_row.row(align=True) prop_btn_row = labeled_row.row(align=True)
render_output = render_output_path(context) render_output = render_output_path(context)
if render_output is None: if render_output is None:
prop_btn_row.label('Unable to render with Flamenco, outside of project directory.') prop_btn_row.label('Unable to render with Flamenco, outside of project directory.')
else: else:
@@ -452,17 +543,22 @@ class FLAMENCO_PT_render(bpy.types.Panel):
text='', icon='DISK_DRIVE') text='', icon='DISK_DRIVE')
props.path = str(render_output.parent) props.path = str(render_output.parent)
layout.operator(FLAMENCO_OT_render.bl_idname, flamenco_status = context.window_manager.flamenco_status
text='Render on Flamenco', if flamenco_status == 'IDLE':
icon='RENDER_ANIMATION') layout.operator(FLAMENCO_OT_render.bl_idname,
text='Render on Flamenco',
if not context.scene.render.use_overwrite: icon='RENDER_ANIMATION')
warnbox = layout.box().column(align=True) elif flamenco_status == 'PACKING':
warnbox.label('Please enable "Overwrite" in the Output panel,') layout.label('Flamenco is packing your file + dependencies')
warnbox.label('or re-queueing this job might not do anything.') elif flamenco_status == 'COMMUNICATING':
layout.label('Communicating with Flamenco Server')
else:
layout.label('Unknown Flamenco status %s' % flamenco_status)
def register(): def register():
from ..utils import redraw
bpy.utils.register_class(FlamencoManagerGroup) bpy.utils.register_class(FlamencoManagerGroup)
bpy.utils.register_class(FLAMENCO_OT_fmanagers) bpy.utils.register_class(FLAMENCO_OT_fmanagers)
bpy.utils.register_class(FLAMENCO_OT_render) bpy.utils.register_class(FLAMENCO_OT_render)
@@ -472,36 +568,61 @@ def register():
bpy.utils.register_class(FLAMENCO_PT_render) bpy.utils.register_class(FLAMENCO_PT_render)
scene = bpy.types.Scene scene = bpy.types.Scene
scene.flamenco_render_chunk_size = IntProperty( scene.flamenco_render_fchunk_size = IntProperty(
name='Chunk size', name='Frame Chunk Size',
description='Maximum number of frames to render per task', description='Maximum number of frames to render per task',
default=10, min=1,
default=1,
)
scene.flamenco_render_schunk_count = IntProperty(
name='Number of Sample Chunks',
description='Number of Cycles samples chunks to use per frame',
min=2,
default=3,
soft_max=10,
) )
scene.flamenco_render_frame_range = StringProperty( scene.flamenco_render_frame_range = StringProperty(
name='Frame range', name='Frame Range',
description='Frames to render, in "printer range" notation' description='Frames to render, in "printer range" notation'
) )
scene.flamenco_render_job_type = EnumProperty( scene.flamenco_render_job_type = EnumProperty(
name='Job type', name='Job Type',
items=[ items=[
('blender-render', 'Simple Blender render', 'Not tiled, not resumable, just render'), ('blender-render', 'Simple Render', 'Simple frame-by-frame render'),
], ('blender-render-progressive', 'Progressive Render',
description='Flamenco render job type', 'Each frame is rendered multiple times with different Cycles sample chunks, then combined'),
]
) )
scene.flamenco_render_job_priority = IntProperty( scene.flamenco_render_job_priority = IntProperty(
name='Job priority', name='Job Priority',
min=0, min=0,
default=50, default=50,
max=100, max=100,
description='Higher numbers mean higher priority' description='Higher numbers mean higher priority'
) )
bpy.types.WindowManager.flamenco_status = EnumProperty(
items=[
('IDLE', 'IDLE', 'Not doing anything.'),
('PACKING', 'PACKING', 'BAM-packing all dependencies.'),
('COMMUNICATING', 'COMMUNICATING', 'Communicating with Flamenco Server.'),
],
name='flamenco_status',
default='IDLE',
description='Current status of the Flamenco add-on',
update=redraw)
def unregister(): def unregister():
bpy.utils.unregister_module(__name__) bpy.utils.unregister_module(__name__)
try: try:
del bpy.types.Scene.flamenco_render_chunk_size del bpy.types.Scene.flamenco_render_fchunk_size
except AttributeError:
pass
try:
del bpy.types.Scene.flamenco_render_schunk_count
except AttributeError: except AttributeError:
pass pass
try: try:
@@ -516,3 +637,7 @@ def unregister():
del bpy.types.Scene.flamenco_render_job_priority del bpy.types.Scene.flamenco_render_job_priority
except AttributeError: except AttributeError:
pass pass
try:
del bpy.types.WindowManager.flamenco_status
except AttributeError:
pass

View File

@@ -860,6 +860,13 @@ class AuthenticatedPillarOperatorMixin(PillarOperatorMixin):
self.report({'ERROR'}, 'Please log in on Blender ID first.') self.report({'ERROR'}, 'Please log in on Blender ID first.')
self.quit() self.quit()
return False return False
except requests.exceptions.ConnectionError:
self.log.exception('Error checking pillar credentials.')
self.report({'ERROR'}, 'Unable to connect to Blender Cloud, '
'check your internet connection.')
self.quit()
return False
self.user_id = self.db_user['_id'] self.user_id = self.db_user['_id']
return True return True

View File

@@ -227,7 +227,7 @@ setup(
'wheels': BuildWheels}, 'wheels': BuildWheels},
name='blender_cloud', name='blender_cloud',
description='The Blender Cloud addon allows browsing the Blender Cloud from Blender.', description='The Blender Cloud addon allows browsing the Blender Cloud from Blender.',
version='1.5.9999', version='1.6.1',
author='Sybren A. Stüvel', author='Sybren A. Stüvel',
author_email='sybren@stuvel.eu', author_email='sybren@stuvel.eu',
packages=find_packages('.'), packages=find_packages('.'),