diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 15f8c23a8bdf34b771587a9047b1281ec02ba69c..9633ae507da55624e8b58b36b36c927504c96aae 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -227,26 +227,10 @@ mesh_poly_types = (
     ('OTHER', 'other', ''),
 )
 
-thumbnail_angles = (
-    ('DEFAULT', 'default', ''),
-    ('FRONT', 'front', ''),
-    ('SIDE', 'side', ''),
-    ('TOP', 'top', ''),
-)
 
-thumbnail_snap = (
-    ('GROUND', 'ground', ''),
-    ('WALL', 'wall', ''),
-    ('CEILING', 'ceiling', ''),
-    ('FLOAT', 'floating', ''),
-)
 
-thumbnail_resolutions = (
-    ('256', '256', ''),
-    ('512', '512', ''),
-    ('1024', '1024 - minimum for public', ''),
-    ('2048', '2048', ''),
-)
+
+
 
 
 def udate_down_up(self, context):
@@ -588,8 +572,30 @@ def update_free(self, context):
                                      " based on our fair share system. " \
                                      "Part of subscription is sent to artists based on usage by paying users.\n")
 
+# common_upload_props = [
+#     {
+#         'identifier':'id',
+#         'name':"Asset Version Id",
+#         'type':'StringProperty',
+#         'description':'Unique name of the asset version(hidden)',
+#         'default':''
+# }
+# {
+#         'identifier':'id',
+#         'name':"Asset Version Id",
+#         'type':'StringProperty',
+#         'description':'Unique name of the asset version(hidden)',
+#         'default':''
+# }
+# ]
+
+
+
 
 class BlenderKitCommonUploadProps(object):
+    # for p in common_upload_props:
+    #     exec(f"{p['identifier']}: {p['type']}(name='{p['name']}',description='{p['description']}',default='{p['default']}')")
+
     id: StringProperty(
         name="Asset Version Id",
         description="Unique name of the asset version(hidden)",
@@ -888,7 +894,7 @@ class BlenderKitMaterialUploadProps(PropertyGroup, BlenderKitCommonUploadProps):
 
     thumbnail_resolution: EnumProperty(
         name="Resolution",
-        items=thumbnail_resolutions,
+        items=autothumb.thumbnail_resolutions,
         description="Thumbnail resolution",
         default="1024",
     )
@@ -1064,21 +1070,21 @@ class BlenderKitModelUploadProps(PropertyGroup, BlenderKitCommonUploadProps):
 
     thumbnail_angle: EnumProperty(
         name='Thumbnail Angle',
-        items=thumbnail_angles,
+        items=autothumb.thumbnail_angles,
         default='DEFAULT',
         description='thumbnailer angle',
     )
 
     thumbnail_snap_to: EnumProperty(
         name='Model Snaps To:',
-        items=thumbnail_snap,
+        items=autothumb.thumbnail_snap,
         default='GROUND',
         description='typical placing of the interior. Leave on ground for most objects that respect gravity :)',
     )
 
     thumbnail_resolution: EnumProperty(
         name="Resolution",
-        items=thumbnail_resolutions,
+        items=autothumb.thumbnail_resolutions,
         description="Thumbnail resolution",
         default="1024",
     )
diff --git a/blenderkit/append_link.py b/blenderkit/append_link.py
index a8b5c7185dbf0a5081ed908206f1d5e7bde79ce3..28b0d24e58d1aa079ad0afaa229209a5abf071f3 100644
--- a/blenderkit/append_link.py
+++ b/blenderkit/append_link.py
@@ -55,23 +55,28 @@ def append_material(file_name, matname=None, link=False, fake_user=True):
                     break;
 
             #not found yet? probably some name inconsistency then.
-            # if not found and len(data_from.materials)>0:
-            #     data_to.materials = data_from.materials[0]
-            #     matname = data_from.materials[0]
-            #     print('had to assign')
+            if not found and len(data_from.materials)>0:
+                data_to.materials = [data_from.materials[0]]
+                matname = data_from.materials[0]
+                print(f"the material wasn't found under the exact name, appended another one: {matname}")
             # print('in the appended file the name is ', matname)
 
     except Exception as e:
         print(e)
         print('failed to open the asset file')
-    # we have to find the new material :(
+    # we have to find the new material , due to possible name changes
+    mat = None
     for m in bpy.data.materials:
+        print(m.name)
         if m not in mats_before:
             mat = m
-            break
+            break;
+    #still not found?
+    if mat is None:
+        mat = bpy.data.materials.get(matname)
+
     if fake_user:
         mat.use_fake_user = True
-
     return mat
 
 
diff --git a/blenderkit/asset_bar_op.py b/blenderkit/asset_bar_op.py
index 41ead99cedfc2f8a2918c08c1004b2a043afd872..acb9cf943891c3d6eca14bcc65f7f03e4be7f4d1 100644
--- a/blenderkit/asset_bar_op.py
+++ b/blenderkit/asset_bar_op.py
@@ -52,6 +52,11 @@ BL_UI_Widget.get_area_height = get_area_height
 
 
 def asset_bar_modal(self, context, event):
+    ui_props = bpy.context.scene.blenderkitUI
+    if ui_props.turn_off:
+        ui_props.turn_off = False
+        self.finish()
+
     if self._finished:
         return {'FINISHED'}
 
@@ -76,7 +81,9 @@ def asset_bar_modal(self, context, event):
         self.scroll_update()
         return {'RUNNING_MODAL'}
 
-
+    if self.check_ui_resized(context):
+        self.update_ui_size(context)
+        self.update_layout(context)
     return {"PASS_THROUGH"}
 
 def asset_bar_invoke(self, context, event):
@@ -235,6 +242,27 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
         for w in self.tooltip_widgets:
             w.visible = True
 
+    def check_ui_resized(self,context):
+        region = context.region
+        area = context.area
+        ui_props = bpy.context.scene.blenderkitUI
+        ui_scale = bpy.context.preferences.view.ui_scale
+
+        reg_multiplier = 1
+        if not bpy.context.preferences.system.use_region_overlap:
+            reg_multiplier = 0
+
+        for r in area.regions:
+            if r.type == 'TOOLS':
+                self.bar_x = r.width * reg_multiplier + self.margin + ui_props.bar_x_offset * ui_scale
+            elif r.type == 'UI':
+                self.bar_end = r.width * reg_multiplier + 100 * ui_scale
+
+        bar_width = region.width - self.bar_x - self.bar_end
+        if bar_width != self.bar_width:
+            return True
+        return False
+
     def update_ui_size(self, context):
 
         if bpy.app.background or not context.area:
@@ -264,16 +292,18 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
             elif r.type == 'UI':
                 self.bar_end = r.width * reg_multiplier + 100 * ui_scale
 
-        self.bar_width = region.width - ui_props.bar_x - ui_props.bar_end
+        self.bar_width = region.width - self.bar_x - self.bar_end
 
         self.wcount = math.floor(
             (self.bar_width) / (self.button_size))
 
         search_results = bpy.context.window_manager.get('search results')
-        if search_results is not None and self.wcount > 0:
-            self.hcount = min(user_preferences.max_assetbar_rows, math.ceil(len(search_results) / self.wcount))
-        else:
-            self.hcount = 1
+        # we need to init all possible thumb previews in advance/
+        self.hcount = user_preferences.max_assetbar_rows
+        # if search_results is not None and self.wcount > 0:
+        #     self.hcount = min(user_preferences.max_assetbar_rows, math.ceil(len(search_results) / self.wcount))
+        # else:
+        #     self.hcount = 1
 
         self.bar_height = (self.button_size) * self.hcount + 2 * self.assetbar_margin
         # self.bar_y = region.height - ui_props.bar_y_offset * ui_scale
@@ -285,6 +315,9 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
             self.reports_y = self.bar_y - self.bar_height - 100
             self.reports_x = self.bar_x
 
+    def update_layout(self, context):
+        pass;
+
     def __init__(self):
         super().__init__()
 
@@ -490,7 +523,14 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
             if img:
                 self.tooltip_image.set_image(img.filepath)
             self.asset_name.text = asset_data['name']
-            self.tooltip_panel.update(widget.x_screen + widget.width, widget.y_screen + widget.height)
+
+            properties_width = 0
+            for r in bpy.context.area.regions:
+                if r.type == 'UI':
+                    properties_width = r.width
+            tooltip_x = min(widget.x_screen + widget.width, bpy.context.region.width - self.tooltip_panel.width -properties_width)
+
+            self.tooltip_panel.update(tooltip_x, widget.y_screen + widget.height)
             self.tooltip_panel.layout_widgets()
 
     def exit_button(self, widget):
@@ -518,8 +558,9 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
             blenderkit.search.search(get_next=True)
 
     def update_images(self):
-        sr = bpy.context.window_manager['search results']
-
+        sr = bpy.context.window_manager.get('search results')
+        if not sr:
+            return
         for asset_button in self.asset_buttons:
             asset_button.asset_index = asset_button.button_index + self.scroll_offset
             if asset_button.asset_index < len(sr):
@@ -580,6 +621,15 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
         self.scroll_offset -= self.wcount * self.hcount
         self.scroll_update()
 
+    def update_sizes(self):
+        properties_width = 0
+        for r in bpy.context.area.regions:
+            if r.type == 'UI':
+                properties_width = r.width
+        tooltip_x = min(widget.x_screen + widget.width,
+                        bpy.context.region.width - self.tooltip_panel.width - properties_width)
+        print(widget.x_screen + widget.width, bpy.context.region.width - self.tooltip_panel.width)
+
 
 def register():
     bpy.utils.register_class(BlenderKitAssetBarOperator)
diff --git a/blenderkit/autothumb.py b/blenderkit/autothumb.py
index 9f47d3c3ce931420b58e3496111af9d327de47ef..26697d7402efc1f9c6715dcbb60a2543a96a366f 100644
--- a/blenderkit/autothumb.py
+++ b/blenderkit/autothumb.py
@@ -16,23 +16,69 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-
-from blenderkit import paths, utils, bg_blender, ui_panels
+from blenderkit import paths, utils, bg_blender, ui_panels, icons, tasks_queue, download
 
 import tempfile, os, subprocess, json, sys
 
 import bpy
+from bpy.props import (
+    FloatProperty,
+    IntProperty,
+    EnumProperty,
+    BoolProperty,
+    StringProperty,
+)
 
 BLENDERKIT_EXPORT_DATA_FILE = "data.json"
 
+thumbnail_resolutions = (
+    ('256', '256', ''),
+    ('512', '512', ''),
+    ('1024', '1024 - minimum for public', ''),
+    ('2048', '2048', ''),
+)
+
+thumbnail_angles = (
+    ('DEFAULT', 'default', ''),
+    ('FRONT', 'front', ''),
+    ('SIDE', 'side', ''),
+    ('TOP', 'top', ''),
+)
+
+thumbnail_snap = (
+    ('GROUND', 'ground', ''),
+    ('WALL', 'wall', ''),
+    ('CEILING', 'ceiling', ''),
+    ('FLOAT', 'floating', ''),
+)
+
+
+def get_texture_ui(tpath, iname):
+    tex = bpy.data.textures.get(iname)
+
+    if tpath.startswith('//'):
+        tpath = bpy.path.abspath(tpath)
+
+    if not tex or not tex.image or not tex.image.filepath == tpath:
+        tasks_queue.add_task((utils.get_hidden_image, (tpath, iname)), only_last=True)
+        tasks_queue.add_task((utils.get_hidden_texture, (iname,)), only_last=True)
+        return None
+    return tex
+
 
 def check_thumbnail(props, imgpath):
     img = utils.get_hidden_image(imgpath, 'upload_preview', force_reload=True)
+    print(' check thumbnail ', img)
     if img is not None:  # and img.size[0] == img.size[1] and img.size[0] >= 512 and (
         # img.file_format == 'JPEG' or img.file_format == 'PNG'):
         props.has_thumbnail = True
         props.thumbnail_generating_state = ''
-        return
+
+        tex = utils.get_hidden_texture(img.name)
+        # pcoll = icons.icon_collections["previews"]
+        # pcoll.load(img.name, img.filepath, 'IMAGE')
+
+        return img
     else:
         props.has_thumbnail = False
     output = ''
@@ -55,7 +101,7 @@ def update_upload_model_preview(self, context):
     if ob is not None:
         props = ob.blenderkit
         imgpath = props.thumbnail
-        check_thumbnail(props, imgpath)
+        img = check_thumbnail(props, imgpath)
 
 
 def update_upload_scene_preview(self, context):
@@ -83,55 +129,19 @@ def update_upload_brush_preview(self, context):
         check_thumbnail(props, imgpath)
 
 
-def start_thumbnailer(self, context):
+def start_thumbnailer(self=None, json_args=None, props=None, wait=False, add_bg_process=True):
     # Prepare to save the file
-    mainmodel = utils.get_active_model()
-    mainmodel.blenderkit.is_generating_thumbnail = True
-    mainmodel.blenderkit.thumbnail_generating_state = 'starting blender instance'
 
     binary_path = bpy.app.binary_path
     script_path = os.path.dirname(os.path.realpath(__file__))
-    basename, ext = os.path.splitext(bpy.data.filepath)
-    if not basename:
-        basename = os.path.join(basename, "temp")
-    if not ext:
-        ext = ".blend"
-    asset_name = mainmodel.name
-    tempdir = tempfile.mkdtemp()
-
-    file_dir = os.path.dirname(bpy.data.filepath)
-    thumb_path = os.path.join(file_dir, asset_name)
-    rel_thumb_path = os.path.join('//', asset_name)
-
-    i = 0
-    while os.path.isfile(thumb_path + '.jpg'):
-        thumb_path = os.path.join(file_dir, asset_name + '_' + str(i).zfill(4))
-        rel_thumb_path = os.path.join('//', asset_name + '_' + str(i).zfill(4))
-        i += 1
-
-    filepath = os.path.join(tempdir, "thumbnailer_blenderkit" + ext)
+
+    ext = '.blend'
+
     tfpath = paths.get_thumbnailer_filepath()
-    datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE)
+    datafile = os.path.join(json_args['tempdir'], BLENDERKIT_EXPORT_DATA_FILE)
     try:
-        # save a copy of actual scene but don't interfere with the users models
-        bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True)
-
-        obs = utils.get_hierarchy(mainmodel)
-        obnames = []
-        for ob in obs:
-            obnames.append(ob.name)
-        with open(datafile, 'w', encoding = 'utf-8') as s:
-            bkit = mainmodel.blenderkit
-            json.dump({
-                "type": "model",
-                "models": str(obnames),
-                "thumbnail_angle": bkit.thumbnail_angle,
-                "thumbnail_snap_to": bkit.thumbnail_snap_to,
-                "thumbnail_background_lightness": bkit.thumbnail_background_lightness,
-                "thumbnail_resolution": bkit.thumbnail_resolution,
-                "thumbnail_samples": bkit.thumbnail_samples,
-                "thumbnail_denoising": bkit.thumbnail_denoising,
-            }, s, ensure_ascii=False, indent=4)
+        with open(datafile, 'w', encoding='utf-8') as s:
+            json.dump(json_args, s, ensure_ascii=False, indent=4)
 
         proc = subprocess.Popen([
             binary_path,
@@ -139,72 +149,49 @@ def start_thumbnailer(self, context):
             "-noaudio",
             tfpath,
             "--python", os.path.join(script_path, "autothumb_model_bg.py"),
-            "--", datafile, filepath, thumb_path, tempdir
+            "--", datafile,
         ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags())
 
-        eval_path_computing = "bpy.data.objects['%s'].blenderkit.is_generating_thumbnail" % mainmodel.name
-        eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % mainmodel.name
-        eval_path = "bpy.data.objects['%s']" % mainmodel.name
+        eval_path_computing = "bpy.data.objects['%s'].blenderkit.is_generating_thumbnail" % json_args['asset_name']
+        eval_path_state = "bpy.data.objects['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name']
+        eval_path = "bpy.data.objects['%s']" % json_args['asset_name']
 
         bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state,
                                   eval_path=eval_path, process_type='THUMBNAILER', process=proc)
 
-        mainmodel.blenderkit.thumbnail = rel_thumb_path + '.jpg'
-        mainmodel.blenderkit.thumbnail_generating_state = 'Saving .blend file'
 
     except Exception as e:
         self.report({'WARNING'}, "Error while exporting file: %s" % str(e))
         return {'FINISHED'}
 
 
-def start_material_thumbnailer(self, context, wait=False):
-    # Prepare to save the file
-    mat = bpy.context.active_object.active_material
-    mat.blenderkit.is_generating_thumbnail = True
-    mat.blenderkit.thumbnail_generating_state = 'starting blender instance'
+def start_material_thumbnailer(self=None, json_args=None, props=None, wait=False, add_bg_process=True):
+    '''
+
+    Parameters
+    ----------
+    self
+    json_args - all arguments:
+    props - blenderkit upload props with thumbnail settings, to communicate back, if not present, not used.
+    wait - wait for the rendering to finish
+
+    Returns
+    -------
+
+    '''
+    if props:
+        props.is_generating_thumbnail = True
+        props.thumbnail_generating_state = 'starting blender instance'
 
     binary_path = bpy.app.binary_path
     script_path = os.path.dirname(os.path.realpath(__file__))
-    basename, ext = os.path.splitext(bpy.data.filepath)
-    if not basename:
-        basename = os.path.join(basename, "temp")
-    if not ext:
-        ext = ".blend"
-    asset_name = mat.name
-    tempdir = tempfile.mkdtemp()
-
-    file_dir = os.path.dirname(bpy.data.filepath)
-
-    thumb_path = os.path.join(file_dir, asset_name)
-    rel_thumb_path = os.path.join('//', mat.name)
-    i = 0
-    while os.path.isfile(thumb_path + '.png'):
-        thumb_path = os.path.join(file_dir, mat.name + '_' + str(i).zfill(4))
-        rel_thumb_path = os.path.join('//', mat.name + '_' + str(i).zfill(4))
-        i += 1
-
-    filepath = os.path.join(tempdir, "material_thumbnailer_cycles" + ext)
+
     tfpath = paths.get_material_thumbnailer_filepath()
-    datafile = os.path.join(tempdir, BLENDERKIT_EXPORT_DATA_FILE)
-    try:
-        # save a copy of actual scene but don't interfere with the users models
-        bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True)
+    datafile = os.path.join(json_args['tempdir'], BLENDERKIT_EXPORT_DATA_FILE)
 
-        with open(datafile, 'w', encoding = 'utf-8') as s:
-            bkit = mat.blenderkit
-            json.dump({
-                "type": "material",
-                "material": mat.name,
-                "thumbnail_type": bkit.thumbnail_generator_type,
-                "thumbnail_scale": bkit.thumbnail_scale,
-                "thumbnail_background": bkit.thumbnail_background,
-                "thumbnail_background_lightness": bkit.thumbnail_background_lightness,
-                "thumbnail_resolution": bkit.thumbnail_resolution,
-                "thumbnail_samples": bkit.thumbnail_samples,
-                "thumbnail_denoising": bkit.thumbnail_denoising,
-                "adaptive_subdivision": bkit.adaptive_subdivision,
-                "texture_size_meters": bkit.texture_size_meters,
-            }, s,  ensure_ascii=False, indent=4)
+    try:
+        with open(datafile, 'w', encoding='utf-8') as s:
+            json.dump(json_args, s, ensure_ascii=False, indent=4)
 
         proc = subprocess.Popen([
             binary_path,
@@ -212,20 +199,28 @@ def start_material_thumbnailer(self, context, wait=False):
             "-noaudio",
             tfpath,
             "--python", os.path.join(script_path, "autothumb_material_bg.py"),
-            "--", datafile, filepath, thumb_path, tempdir
+            "--", datafile,
         ], bufsize=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE, creationflags=utils.get_process_flags())
 
-        eval_path_computing = "bpy.data.materials['%s'].blenderkit.is_generating_thumbnail" % mat.name
-        eval_path_state = "bpy.data.materials['%s'].blenderkit.thumbnail_generating_state" % mat.name
-        eval_path = "bpy.data.materials['%s']" % mat.name
+        eval_path_computing = "bpy.data.materials['%s'].blenderkit.is_generating_thumbnail" % json_args['asset_name']
+        eval_path_state = "bpy.data.materials['%s'].blenderkit.thumbnail_generating_state" % json_args['asset_name']
+        eval_path = "bpy.data.materials['%s']" % json_args['asset_name']
 
-        bg_blender.add_bg_process(eval_path_computing=eval_path_computing, eval_path_state=eval_path_state,
+        bg_blender.add_bg_process(name=json_args['asset_name'], eval_path_computing=eval_path_computing,
+                                  eval_path_state=eval_path_state,
                                   eval_path=eval_path, process_type='THUMBNAILER', process=proc)
+        if props:
+            props.thumbnail_generating_state = 'Saving .blend file'
 
-        mat.blenderkit.thumbnail = rel_thumb_path + '.png'
-        mat.blenderkit.thumbnail_generating_state = 'Saving .blend file'
+        if wait:
+            while proc.poll() is None:
+                stdout_data, stderr_data = proc.communicate()
+                print(stdout_data)
     except Exception as e:
-        self.report({'WARNING'}, "Error while packing file: %s" % str(e))
+        if self:
+            self.report({'WARNING'}, "Error while packing file: %s" % str(e))
+        else:
+            print(e)
         return {'FINISHED'}
 
 
@@ -256,24 +251,198 @@ class GenerateThumbnailOperator(bpy.types.Operator):
         layout.prop(preferences, "thumbnail_use_gpu")
 
     def execute(self, context):
-        start_thumbnailer(self, context)
+        asset = utils.get_active_model()
+        asset.blenderkit.is_generating_thumbnail = True
+        asset.blenderkit.thumbnail_generating_state = 'starting blender instance'
+
+        tempdir = tempfile.mkdtemp()
+        ext = '.blend'
+        filepath = os.path.join(tempdir, "thumbnailer_blenderkit" + ext)
+
+        path_can_be_relative = True
+        file_dir = os.path.dirname(bpy.data.filepath)
+        if file_dir == '':
+            file_dir = tempdir
+            path_can_be_relative = False
+
+        an_slug = paths.slugify(asset.name)
+        thumb_path = os.path.join(file_dir, an_slug)
+        if path_can_be_relative:
+            rel_thumb_path = os.path.join('//', an_slug)
+        else:
+            rel_thumb_path = thumb_path
+
+
+        i = 0
+        while os.path.isfile(thumb_path + '.jpg'):
+            thumb_path = os.path.join(file_dir, an_slug + '_' + str(i).zfill(4))
+            rel_thumb_path = os.path.join('//', an_slug + '_' + str(i).zfill(4))
+            i += 1
+        bkit = asset.blenderkit
+
+        bkit.thumbnail = rel_thumb_path + '.jpg'
+        bkit.thumbnail_generating_state = 'Saving .blend file'
+
+        # save a copy of actual scene but don't interfere with the users models
+        bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True)
+        # get all included objects
+        obs = utils.get_hierarchy(asset)
+        obnames = []
+        for ob in obs:
+            obnames.append(ob.name)
+
+        args_dict = {
+            "type": "material",
+            "asset_name": asset.name,
+            "filepath": filepath,
+            "thumbnail_path": thumb_path,
+            "tempdir": tempdir,
+        }
+        thumbnail_args = {
+            "type": "model",
+            "models": str(obnames),
+            "thumbnail_angle": bkit.thumbnail_angle,
+            "thumbnail_snap_to": bkit.thumbnail_snap_to,
+            "thumbnail_background_lightness": bkit.thumbnail_background_lightness,
+            "thumbnail_resolution": bkit.thumbnail_resolution,
+            "thumbnail_samples": bkit.thumbnail_samples,
+            "thumbnail_denoising": bkit.thumbnail_denoising,
+        }
+        args_dict.update(thumbnail_args)
+
+        start_thumbnailer(self,
+                          json_args=args_dict,
+                          props=asset.blenderkit, wait=False)
         return {'FINISHED'}
 
     def invoke(self, context, event):
         wm = context.window_manager
-        if bpy.data.filepath == '':
-            ui_panels.ui_message(
-                        title = "Can't render thumbnail",
-                        message = "please save your file first")
+        # if bpy.data.filepath == '':
+        #     ui_panels.ui_message(
+        #         title="Can't render thumbnail",
+        #         message="please save your file first")
+        #
+        #     return {'FINISHED'}
+
+        return wm.invoke_props_dialog(self)
+
+
+class ReGenerateThumbnailOperator(bpy.types.Operator):
+    """Generate Cycles thumbnail for model assets"""
+    bl_idname = "object.blenderkit_regenerate_thumbnail"
+    bl_label = "BlenderKit Thumbnail Re-generate"
+    bl_options = {'REGISTER', 'INTERNAL'}
+
+    asset_index: IntProperty(name="Asset Index", description='asset index in search results', default=-1)
+
+    thumbnail_background_lightness: FloatProperty(name="Thumbnail Background Lightness",
+                                                  description="set to make your material stand out", default=1.0,
+                                                  min=0.01, max=10)
+
+    thumbnail_angle: EnumProperty(
+        name='Thumbnail Angle',
+        items=thumbnail_angles,
+        default='DEFAULT',
+        description='thumbnailer angle',
+    )
+
+    thumbnail_snap_to: EnumProperty(
+        name='Model Snaps To:',
+        items=thumbnail_snap,
+        default='GROUND',
+        description='typical placing of the interior. Leave on ground for most objects that respect gravity :)',
+    )
+
+    thumbnail_resolution: EnumProperty(
+        name="Resolution",
+        items=thumbnail_resolutions,
+        description="Thumbnail resolution",
+        default="1024",
+    )
+
+    thumbnail_samples: IntProperty(name="Cycles Samples",
+                                   description="cycles samples setting", default=100,
+                                   min=5, max=5000)
+    thumbnail_denoising: BoolProperty(name="Use Denoising",
+                                      description="Use denoising", default=True)
+
+    @classmethod
+    def poll(cls, context):
+        return True  # bpy.context.view_layer.objects.active is not None
+
+    def draw(self, context):
+        ob = bpy.context.active_object
+        while ob.parent is not None:
+            ob = ob.parent
+        props = self
+        layout = self.layout
+        layout.label(text='thumbnailer settings')
+        layout.prop(props, 'thumbnail_background_lightness')
+        layout.prop(props, 'thumbnail_angle')
+        layout.prop(props, 'thumbnail_snap_to')
+        layout.prop(props, 'thumbnail_samples')
+        layout.prop(props, 'thumbnail_resolution')
+        layout.prop(props, 'thumbnail_denoising')
+        preferences = bpy.context.preferences.addons['blenderkit'].preferences
+        layout.prop(preferences, "thumbnail_use_gpu")
 
-            return {'FINISHED'}
+    def execute(self, context):
+        if not self.asset_index > -1:
+            return {'CANCELLED'}
+
+        # either get the data from search results
+        sr = bpy.context.window_manager['search results']
+        asset_data = sr[self.asset_index].to_dict()
+
+        tempdir = tempfile.mkdtemp()
+
+        an_slug = paths.slugify(asset_data['name'])
+        thumb_path = os.path.join(tempdir, an_slug)
+
+
+        args_dict = {
+            "type": "material",
+            "asset_name": asset_data['name'],
+            "asset_data": asset_data,
+            # "filepath": filepath,
+            "thumbnail_path": thumb_path,
+            "tempdir": tempdir,
+            "do_download": True,
+            "upload_after_render": True,
+        }
+        thumbnail_args = {
+            "type": "model",
+            "thumbnail_angle": self.thumbnail_angle,
+            "thumbnail_snap_to": self.thumbnail_snap_to,
+            "thumbnail_background_lightness": self.thumbnail_background_lightness,
+            "thumbnail_resolution": self.thumbnail_resolution,
+            "thumbnail_samples": self.thumbnail_samples,
+            "thumbnail_denoising": self.thumbnail_denoising,
+        }
+        args_dict.update(thumbnail_args)
+
+        start_thumbnailer(self,
+                          json_args=args_dict,
+                          wait=False)
+        return {'FINISHED'}
+        start_thumbnailer(self, context)
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        wm = context.window_manager
+        # if bpy.data.filepath == '':
+        #     ui_panels.ui_message(
+        #         title="Can't render thumbnail",
+        #         message="please save your file first")
+        #
+        #     return {'FINISHED'}
 
         return wm.invoke_props_dialog(self)
 
 
 class GenerateMaterialThumbnailOperator(bpy.types.Operator):
     """Generate default thumbnail with Cycles renderer."""
-    bl_idname = "object.blenderkit_material_thumbnail"
+    bl_idname = "object.blenderkit_generate_material_thumbnail"
     bl_label = "BlenderKit Material Thumbnail Generator"
     bl_options = {'REGISTER', 'INTERNAL'}
 
@@ -300,7 +469,48 @@ class GenerateMaterialThumbnailOperator(bpy.types.Operator):
         layout.prop(preferences, "thumbnail_use_gpu")
 
     def execute(self, context):
-        start_material_thumbnailer(self, context)
+        asset = bpy.context.active_object.active_material
+        tempdir = tempfile.mkdtemp()
+        filepath = os.path.join(tempdir, "material_thumbnailer_cycles.blend")
+        # save a copy of actual scene but don't interfere with the users models
+        bpy.ops.wm.save_as_mainfile(filepath=filepath, compress=False, copy=True)
+
+        thumb_dir = os.path.dirname(bpy.data.filepath)
+        thumb_path = os.path.join(thumb_dir, asset.name)
+        rel_thumb_path = os.path.join('//', asset.name)
+        # auto increase number of the generated thumbnail.
+        i = 0
+        while os.path.isfile(thumb_path + '.png'):
+            thumb_path = os.path.join(thumb_dir, asset.name + '_' + str(i).zfill(4))
+            rel_thumb_path = os.path.join('//', asset.name + '_' + str(i).zfill(4))
+            i += 1
+
+        asset.blenderkit.thumbnail = rel_thumb_path + '.png'
+        bkit = asset.blenderkit
+
+        args_dict = {
+            "type": "material",
+            "asset_name": asset.name,
+            "filepath": filepath,
+            "thumbnail_path": thumb_path,
+            "tempdir": tempdir,
+        }
+
+        thumbnail_args = {
+            "thumbnail_type": bkit.thumbnail_generator_type,
+            "thumbnail_scale": bkit.thumbnail_scale,
+            "thumbnail_background": bkit.thumbnail_background,
+            "thumbnail_background_lightness": bkit.thumbnail_background_lightness,
+            "thumbnail_resolution": bkit.thumbnail_resolution,
+            "thumbnail_samples": bkit.thumbnail_samples,
+            "thumbnail_denoising": bkit.thumbnail_denoising,
+            "adaptive_subdivision": bkit.adaptive_subdivision,
+            "texture_size_meters": bkit.texture_size_meters,
+        }
+        args_dict.update(thumbnail_args)
+        start_material_thumbnailer(self,
+                                   json_args=args_dict,
+                                   props=asset.blenderkit, wait=False)
 
         return {'FINISHED'}
 
@@ -309,11 +519,144 @@ class GenerateMaterialThumbnailOperator(bpy.types.Operator):
         return wm.invoke_props_dialog(self)
 
 
+class ReGenerateMaterialThumbnailOperator(bpy.types.Operator):
+    """
+        Generate default thumbnail with Cycles renderer.
+        Works also for assets from search results, without being downloaded before.
+    """
+    bl_idname = "object.blenderkit_regenerate_material_thumbnail"
+    bl_label = "BlenderKit Material Thumbnail Re-Generator"
+    bl_options = {'REGISTER', 'INTERNAL'}
+
+    asset_index: IntProperty(name="Asset Index", description='asset index in search results', default=-1)
+
+    thumbnail_scale: FloatProperty(name="Thumbnail Object Size",
+                                   description="Size of material preview object in meters."
+                                               "Change for materials that look better at sizes different than 1m",
+                                   default=1, min=0.00001, max=10)
+    thumbnail_background: BoolProperty(name="Thumbnail Background (for Glass only)",
+                                       description="For refractive materials, you might need a background.\n"
+                                                   "Don't use for other types of materials.\n"
+                                                   "Transparent background is preferred",
+                                       default=False)
+    thumbnail_background_lightness: FloatProperty(name="Thumbnail Background Lightness",
+                                                  description="Set to make your material stand out with enough contrast",
+                                                  default=.9,
+                                                  min=0.00001, max=1)
+    thumbnail_samples: IntProperty(name="Cycles Samples",
+                                   description="Cycles samples", default=100,
+                                   min=5, max=5000)
+    thumbnail_denoising: BoolProperty(name="Use Denoising",
+                                      description="Use denoising", default=True)
+    adaptive_subdivision: BoolProperty(name="Adaptive Subdivide",
+                                       description="Use adaptive displacement subdivision", default=False)
+
+    thumbnail_resolution: EnumProperty(
+        name="Resolution",
+        items=thumbnail_resolutions,
+        description="Thumbnail resolution",
+        default="1024",
+    )
+
+    thumbnail_generator_type: EnumProperty(
+        name="Thumbnail Style",
+        items=(
+            ('BALL', 'Ball', ""),
+            ('BALL_COMPLEX', 'Ball complex', 'Complex ball to highlight edgewear or material thickness'),
+            ('FLUID', 'Fluid', 'Fluid'),
+            ('CLOTH', 'Cloth', 'Cloth'),
+            ('HAIR', 'Hair', 'Hair  ')
+        ),
+        description="Style of asset",
+        default="BALL",
+    )
+
+    @classmethod
+    def poll(cls, context):
+        return True  # bpy.context.view_layer.objects.active is not None
+
+    def check(self, context):
+        return True
+
+    def draw(self, context):
+        layout = self.layout
+        props = self
+        layout.prop(props, 'thumbnail_generator_type')
+        layout.prop(props, 'thumbnail_scale')
+        layout.prop(props, 'thumbnail_background')
+        if props.thumbnail_background:
+            layout.prop(props, 'thumbnail_background_lightness')
+        layout.prop(props, 'thumbnail_resolution')
+        layout.prop(props, 'thumbnail_samples')
+        layout.prop(props, 'thumbnail_denoising')
+        layout.prop(props, 'adaptive_subdivision')
+        preferences = bpy.context.preferences.addons['blenderkit'].preferences
+        layout.prop(preferences, "thumbnail_use_gpu")
+
+    def execute(self, context):
+
+        if not self.asset_index > -1:
+            return {'CANCELLED'}
+
+        # either get the data from search results
+        sr = bpy.context.window_manager['search results']
+        asset_data = sr[self.asset_index].to_dict()
+
+        tempdir = tempfile.mkdtemp()
+
+        thumb_path = os.path.join(tempdir, asset_data['name'])
+
+        args_dict = {
+            "type": "material",
+            "asset_name": asset_data['name'],
+            "asset_data": asset_data,
+            "thumbnail_path": thumb_path,
+            "tempdir": tempdir,
+            "do_download": True,
+            "upload_after_render": True,
+        }
+        thumbnail_args = {
+            "thumbnail_type": self.thumbnail_generator_type,
+            "thumbnail_scale": self.thumbnail_scale,
+            "thumbnail_background": self.thumbnail_background,
+            "thumbnail_background_lightness": self.thumbnail_background_lightness,
+            "thumbnail_resolution": self.thumbnail_resolution,
+            "thumbnail_samples": self.thumbnail_samples,
+            "thumbnail_denoising": self.thumbnail_denoising,
+            "adaptive_subdivision": self.adaptive_subdivision,
+            "texture_size_meters": utils.get_param(asset_data, 'textureSizeMeters', 1.0),
+        }
+        args_dict.update(thumbnail_args)
+        start_material_thumbnailer(self,
+                                   json_args=args_dict,
+                                   wait=False)
+
+        return {'FINISHED'}
+
+    def invoke(self, context, event):
+        # scene = bpy.context.scene
+        # ui_props = scene.blenderkitUI
+        # if ui_props.active_index > -1:
+        #     sr = bpy.context.window_manager['search results']
+        #     self.asset_data = dict(sr[ui_props.active_index])
+        # else:
+        #
+        #     active_asset = utils.get_active_asset_by_type(asset_type = self.asset_type)
+        #     self.asset_data = active_asset.get('asset_data')
+
+        wm = context.window_manager
+        return wm.invoke_props_dialog(self)
+
+
 def register_thumbnailer():
     bpy.utils.register_class(GenerateThumbnailOperator)
+    bpy.utils.register_class(ReGenerateThumbnailOperator)
     bpy.utils.register_class(GenerateMaterialThumbnailOperator)
+    bpy.utils.register_class(ReGenerateMaterialThumbnailOperator)
 
 
 def unregister_thumbnailer():
     bpy.utils.unregister_class(GenerateThumbnailOperator)
+    bpy.utils.unregister_class(ReGenerateThumbnailOperator)
     bpy.utils.unregister_class(GenerateMaterialThumbnailOperator)
+    bpy.utils.unregister_class(ReGenerateMaterialThumbnailOperator)
diff --git a/blenderkit/autothumb_material_bg.py b/blenderkit/autothumb_material_bg.py
index d27d7b90ad05903da48733b52dd54333c6aad662..0a0ce5dbd2a4f044ee96b4b2495c7624c202c0df 100644
--- a/blenderkit/autothumb_material_bg.py
+++ b/blenderkit/autothumb_material_bg.py
@@ -18,16 +18,14 @@
 
 
 
-from blenderkit import utils, append_link, bg_blender
+from blenderkit import utils, append_link, bg_blender, upload_bg, download
 
 import sys, json, math
 import bpy
 from pathlib import Path
 
-BLENDERKIT_EXPORT_TEMP_DIR = sys.argv[-1]
-BLENDERKIT_THUMBNAIL_PATH = sys.argv[-2]
-BLENDERKIT_EXPORT_FILE_INPUT = sys.argv[-3]
-BLENDERKIT_EXPORT_DATA = sys.argv[-4]
+
+BLENDERKIT_EXPORT_DATA = sys.argv[-1]
 
 
 def render_thumbnails():
@@ -44,13 +42,26 @@ def unhide_collection(cname):
 if __name__ == "__main__":
     try:
         bg_blender.progress('preparing thumbnail scene')
+        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
+
         with open(BLENDERKIT_EXPORT_DATA, 'r',encoding='utf-8') as s:
             data = json.load(s)
             # append_material(file_name, matname = None, link = False, fake_user = True)
-        mat = append_link.append_material(file_name=BLENDERKIT_EXPORT_FILE_INPUT, matname=data["material"], link=True,
+        if data.get('do_download'):
+            asset_data = data['asset_data']
+            has_url = download.get_download_url(asset_data, download.get_scene_id(), user_preferences.api_key, tcom=None,
+                                                resolution='blend')
+            if not has_url:
+                bg_blender.progress("couldn't download asset for thumnbail re-rendering")
+                exit()
+            # download first, or rather make sure if it's already downloaded
+            bg_blender.progress('downloading asset')
+            fpath = download.download_asset_file(asset_data)
+            data['filepath'] = fpath
+
+        mat = append_link.append_material(file_name=data['filepath'], matname=data["asset_name"], link=True,
                                           fake_user=False)
 
-        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
 
         s = bpy.context.scene
 
@@ -61,7 +72,6 @@ if __name__ == "__main__":
             'CLOTH': 'Cloth',
             'HAIR': 'Hair'
         }
-
         unhide_collection(colmapdict[data["thumbnail_type"]])
         if data['thumbnail_background']:
             unhide_collection('Background')
@@ -70,6 +80,9 @@ if __name__ == "__main__":
         tscale = data["thumbnail_scale"]
         bpy.context.view_layer.objects['scaler'].scale = (tscale, tscale, tscale)
         bpy.context.view_layer.update()
+        print('we have this materialB')
+        print(mat)
+
         for ob in bpy.context.visible_objects:
             if ob.name[:15] == 'MaterialPreview':
                 ob.material_slots[0].material = mat
@@ -86,6 +99,7 @@ if __name__ == "__main__":
                 if data["thumbnail_type"] in ['BALL', 'BALL_COMPLEX', 'CLOTH']:
                    utils.automap(ob.name, tex_size = ts / tscale, just_scale = True, bg_exception=True)
         bpy.context.view_layer.update()
+        print('got to C')
 
         s.cycles.volume_step_size = tscale * .1
 
@@ -113,9 +127,24 @@ if __name__ == "__main__":
         bpy.context.scene.render.resolution_x = int(data['thumbnail_resolution'])
         bpy.context.scene.render.resolution_y = int(data['thumbnail_resolution'])
 
-        bpy.context.scene.render.filepath = BLENDERKIT_THUMBNAIL_PATH
+        bpy.context.scene.render.filepath = data['thumbnail_path']
         bg_blender.progress('rendering thumbnail')
         render_thumbnails()
+        if data.get('upload_after_render') and data.get('asset_data'):
+            bg_blender.progress('uploading thumbnail')
+            preferences = bpy.context.preferences.addons['blenderkit'].preferences
+
+            file = {
+                "type": "thumbnail",
+                "index": 0,
+                "file_path": data['thumbnail_path'] + '.png'
+            }
+            upload_data = {
+                "name": data['asset_data']['name'],
+                "token": preferences.api_key,
+                "id": data['asset_data']['id']
+            }
+            upload_bg.upload_file(upload_data, file)
         bg_blender.progress('background autothumbnailer finished successfully')
 
 
diff --git a/blenderkit/autothumb_model_bg.py b/blenderkit/autothumb_model_bg.py
index 87acfa1904a0c9b8c761f3eb219969a525bd53f3..9be56d9f75c2512fe466c0766596c0216013e6c9 100644
--- a/blenderkit/autothumb_model_bg.py
+++ b/blenderkit/autothumb_model_bg.py
@@ -18,17 +18,14 @@
 
 
 
-from blenderkit import utils, append_link, bg_blender
+from blenderkit import utils, append_link, bg_blender, download, upload_bg
 
 import sys, json, math
 from pathlib import Path
 import bpy
 import mathutils
 
-BLENDERKIT_EXPORT_TEMP_DIR = sys.argv[-1]
-BLENDERKIT_THUMBNAIL_PATH = sys.argv[-2]
-BLENDERKIT_EXPORT_FILE_INPUT = sys.argv[-3]
-BLENDERKIT_EXPORT_DATA = sys.argv[-4]
+BLENDERKIT_EXPORT_DATA = sys.argv[-1]
 
 
 def get_obnames():
@@ -42,6 +39,8 @@ def center_obs_for_thumbnail(obs):
     s = bpy.context.scene
     # obs = bpy.context.selected_objects
     parent = obs[0]
+    if parent.type == 'EMPTY' and parent.instance_collection is not None:
+        obs = parent.instance_collection.objects[:]
 
     while parent.parent != None:
         parent = parent.parent
@@ -79,18 +78,42 @@ def render_thumbnails():
 
 if __name__ == "__main__":
     try:
+        print( 'got to A')
         with open(BLENDERKIT_EXPORT_DATA, 'r',encoding='utf-8') as s:
             data = json.load(s)
 
         user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
 
-        bg_blender.progress('preparing thumbnail scene')
-        obnames = get_obnames()
-        main_object, allobs = append_link.append_objects(file_name=BLENDERKIT_EXPORT_FILE_INPUT,
+
+        if data.get('do_download'):
+            bg_blender.progress('Downloading asset')
+
+            asset_data = data['asset_data']
+            has_url = download.get_download_url(asset_data, download.get_scene_id(), user_preferences.api_key, tcom=None,
+                                                resolution='blend')
+            if not has_url == True:
+                bg_blender.progress("couldn't download asset for thumnbail re-rendering")
+            # download first, or rather make sure if it's already downloaded
+            bg_blender.progress('downloading asset')
+            fpath = download.download_asset_file(asset_data)
+            data['filepath'] = fpath
+            main_object, allobs = append_link.link_collection(fpath,
+                                                          location=(0,0,0),
+                                                          rotation=(0,0,0),
+                                                          link=True,
+                                                          name=asset_data['name'],
+                                                          parent=None)
+            allobs = [main_object]
+        else:
+            bg_blender.progress('preparing thumbnail scene')
+
+            obnames = get_obnames()
+            main_object, allobs = append_link.append_objects(file_name=data['filepath'],
                                                          obnames=obnames,
-                                                         link=True)
+                                                             link=True)
         bpy.context.view_layer.update()
 
+
         camdict = {
             'GROUND': 'camera ground',
             'WALL': 'camera wall',
@@ -100,7 +123,7 @@ if __name__ == "__main__":
 
         bpy.context.scene.camera = bpy.data.objects[camdict[data['thumbnail_snap_to']]]
         center_obs_for_thumbnail(allobs)
-        bpy.context.scene.render.filepath = BLENDERKIT_THUMBNAIL_PATH
+        bpy.context.scene.render.filepath = data['thumbnail_path']
         if user_preferences.thumbnail_use_gpu:
             bpy.context.scene.cycles.device = 'GPU'
 
@@ -112,6 +135,7 @@ if __name__ == "__main__":
         }
         s = bpy.context.scene
         s.frame_set(fdict[data['thumbnail_angle']])
+        print( 'got to C')
 
         snapdict = {
             'GROUND': 'Ground',
@@ -131,6 +155,7 @@ if __name__ == "__main__":
         s.cycles.samples = data['thumbnail_samples']
         bpy.context.view_layer.cycles.use_denoising = data['thumbnail_denoising']
         bpy.context.view_layer.update()
+        print( 'got to D')
 
         # import blender's HDR here
         # hdr_path = Path('datafiles/studiolights/world/interior.exr')
@@ -152,10 +177,32 @@ if __name__ == "__main__":
 
         bg_blender.progress('rendering thumbnail')
         render_thumbnails()
-        fpath = BLENDERKIT_THUMBNAIL_PATH + '0001.jpg'
+        fpath = data['thumbnail_path'] + '.jpg'
+        if data.get('upload_after_render') and data.get('asset_data'):
+            bg_blender.progress('uploading thumbnail')
+            preferences = bpy.context.preferences.addons['blenderkit'].preferences
+            print('uploading A')
+            file = {
+                "type": "thumbnail",
+                "index": 0,
+                "file_path": fpath
+            }
+            upload_data = {
+                "name": data['asset_data']['name'],
+                "token": preferences.api_key,
+                "id": data['asset_data']['id']
+            }
+            print('uploading B')
+
+            upload_bg.upload_file(upload_data, file)
+            print('uploading C')
+
         bg_blender.progress('background autothumbnailer finished successfully')
 
 
+        print( 'got to E')
+
+
     except:
         import traceback
 
diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py
index bdce32afc3eabe3ee12136bf432caa98b2c955c9..01c62538656c41a0a9170a57b564ee9778fd949e 100644
--- a/blenderkit/bg_blender.py
+++ b/blenderkit/bg_blender.py
@@ -56,6 +56,9 @@ def threadread(tcom):
     fills the data, dies.'''
     found = False
     while not found:
+        if tcom.proc.poll() is not None:
+            #process terminated
+            return
         inline = tcom.proc.stdout.readline()
         # print('readthread', time.time())
         inline = str(inline)
@@ -111,7 +114,15 @@ def bg_update():
     global bg_processes
     if len(bg_processes) == 0:
         return 2
+    #cleanup dead processes first
+    remove_processes = []
+    for p in bg_processes:
+        if p[1].proc.poll() is not None:
+            remove_processes.append(p)
+    for p in remove_processes:
+        bg_processes.remove(p)
 
+    #Parse process output
     for p in bg_processes:
         # proc=p[1].proc
         readthread = p[0]
@@ -119,26 +130,29 @@ def bg_update():
         if not readthread.is_alive():
             readthread.join()
             # readthread.
+            estring = None
             if tcom.error:
                 estring = tcom.eval_path_computing + ' = False'
-                exec(estring)
-
             tcom.lasttext = tcom.outtext
             if tcom.outtext != '':
                 tcom.outtext = ''
                 text =tcom.lasttext.replace("'","")
                 estring = tcom.eval_path_state + ' = text'
-
-                exec(estring)
             # print(tcom.lasttext)
             if 'finished successfully' in tcom.lasttext:
                 bg_processes.remove(p)
                 estring = tcom.eval_path_computing + ' = False'
-                exec(estring)
             else:
                 readthread = threading.Thread(target=threadread, args=([tcom]), daemon=True)
                 readthread.start()
                 p[0] = readthread
+            if estring:
+                try:
+                    exec(estring)
+                except Exception as e:
+                    print('Exception while reading from background process')
+                    print(e)
+
     # if len(bg_processes) == 0:
     #     bpy.app.timers.unregister(bg_update)
     if len(bg_processes) > 0:
diff --git a/blenderkit/blendfiles/material_thumbnailer_cycles.blend b/blenderkit/blendfiles/material_thumbnailer_cycles.blend
index 23df6817367adeb3f70b845bb29ed810889c7616..1faa5807d4818aa3ba62084167a92d6b42165574 100644
Binary files a/blenderkit/blendfiles/material_thumbnailer_cycles.blend and b/blenderkit/blendfiles/material_thumbnailer_cycles.blend differ
diff --git a/blenderkit/categories.py b/blenderkit/categories.py
index 2da830cb8a33e3edb6c281591e4ad0f082727c58..f91fe512d9d0c317991c51e53bb2e1ab9e9bd9d9 100644
--- a/blenderkit/categories.py
+++ b/blenderkit/categories.py
@@ -17,7 +17,7 @@
 # ##### END GPL LICENSE BLOCK #####
 
 
-from blenderkit import paths, utils, tasks_queue, rerequests
+from blenderkit import paths, utils, tasks_queue, rerequests, ui, colors
 
 import requests
 import json
@@ -233,7 +233,9 @@ def fetch_categories(API_key, force=False):
                 json.dump(categories, s, ensure_ascii=False, indent=4)
         tasks_queue.add_task((load_categories, ()))
     except Exception as e:
-        bk_logger.debug('category fetching failed')
+        t = 'BlenderKit failed to download fresh categories from the server'
+        tasks_queue.add_task((ui.add_report,(t, 15, colors.RED)))
+        bk_logger.debug(t)
         bk_logger.exception(e)
         if not os.path.exists(categories_filepath):
             source_path = paths.get_addon_file(subpath='data' + os.sep + 'categories.json')
diff --git a/blenderkit/download.py b/blenderkit/download.py
index 5d14ee415423ab0aa3f63371729a704437fcb46c..eca35c4150edaddc46eadb6b4785611490840871 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -492,6 +492,8 @@ def append_asset(asset_data, **kwargs):  # downloaders=[], location=None,
     udpate_asset_data_in_dicts(asset_data)
 
     asset_main['asset_data'] = asset_data  # TODO remove this??? should write to blenderkit Props?
+    asset_main.blenderkit.asset_base_id = asset_data['assetBaseId']
+    asset_main.blenderkit.id = asset_data['id']
     bpy.ops.wm.undo_push_context(message='add %s to scene' % asset_data['name'])
     # moving reporting to on save.
     # report_use_success(asset_data['id'])
@@ -683,7 +685,7 @@ def delete_unfinished_file(file_name):
     return
 
 
-def download_file(asset_data, resolution='blend'):
+def download_asset_file(asset_data, resolution='blend', api_key = ''):
     # this is a simple non-threaded way to download files for background resolution genenration tool
     file_name = paths.get_download_filepaths(asset_data, resolution)[0]  # prefer global dir if possible.
 
@@ -691,14 +693,11 @@ def download_file(asset_data, resolution='blend'):
         # this sends the thread for processing, where another check should occur, since the file might be corrupted.
         bk_logger.debug('not downloading, already in db')
         return file_name
-    preferences = bpy.context.preferences.addons['blenderkit'].preferences
-    api_key = preferences.api_key
 
     download_canceled = False
 
     with open(file_name, "wb") as f:
         print("Downloading %s" % file_name)
-        headers = utils.get_headers(api_key)
         res_file_info, resolution = paths.get_res_file(asset_data, resolution)
         response = requests.get(res_file_info['url'], stream=True)
         total_length = response.headers.get('Content-Length')
@@ -1110,18 +1109,18 @@ def get_download_url(asset_data, scene_id, api_key, tcom=None, resolution='blend
     tasks_queue.add_task((ui.add_report, (str(r), 10, colors.RED)))
 
     if r.status_code == 403:
-        r = 'You need Full plan to get this item.'
+        report = 'You need Full plan to get this item.'
         # r1 = 'All materials and brushes are available for free. Only users registered to Standard plan can use all models.'
         # tasks_queue.add_task((ui.add_report, (r1, 5, colors.RED)))
         if tcom is not None:
-            tcom.report = r
+            tcom.report = report
             tcom.error = True
 
     if r.status_code == 404:
-        r = 'Url not found - 404.'
+        report = 'Url not found - 404.'
         # r1 = 'All materials and brushes are available for free. Only users registered to Standard plan can use all models.'
         if tcom is not None:
-            tcom.report = r
+            tcom.report = report
             tcom.error = True
 
     elif r.status_code >= 500:
diff --git a/blenderkit/icons.py b/blenderkit/icons.py
index 5d877b253b7cb1e8d13bfa8d1c76d0f7ce168247..45c729df3bfa06f184d04dd132bdb2427b2c7290 100644
--- a/blenderkit/icons.py
+++ b/blenderkit/icons.py
@@ -51,6 +51,7 @@ def register_icons():
         # iprev.image_pixels_float = img.pixels[:]
 
     icon_collections["main"] = pcoll
+    icon_collections["previews"] = bpy.utils.previews.new()
 
 
 def unregister_icons():
diff --git a/blenderkit/resolutions.py b/blenderkit/resolutions.py
index b2a5e806f85033a4d7bdb9cbe72a323cd17582b3..1a4af5fc728ed9438cbefea8e9506483ca2bc59f 100644
--- a/blenderkit/resolutions.py
+++ b/blenderkit/resolutions.py
@@ -410,7 +410,7 @@ def regenerate_thumbnail_material(data):
     # preferences = bpy.context.preferences.addons['blenderkit'].preferences
     # layout.prop(preferences, "thumbnail_use_gpu")
     # TODO: here it should call start_material_thumbnailer , but with the wait property on, so it can upload afterwards.
-    bpy.ops.object.blenderkit_material_thumbnail()
+    bpy.ops.object.blenderkit_generate_material_thumbnail()
     time.sleep(130)
     # save
     # this does the actual job
@@ -525,7 +525,7 @@ def download_asset(asset_data, resolution='blend', unpack=False, api_key=''):
     has_url = download.get_download_url(asset_data, download.get_scene_id(), api_key, tcom=None,
                                         resolution='blend')
     if has_url:
-        fpath = download.download_file(asset_data)
+        fpath = download.download_asset_file(asset_data, api_key = api_key)
         if fpath and unpack and asset_data['assetType'] != 'hdr':
             send_to_bg(asset_data, fpath, command='unpack', wait=True)
         return fpath
diff --git a/blenderkit/search.py b/blenderkit/search.py
index d802973bda29ab6c2d769a624528cbb6ac44235a..1465d10380d0478a74b5e9eceb242ff6ce9c1a2e 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -48,7 +48,7 @@ import copy
 import json
 import math
 import unicodedata
-
+import queue
 import logging
 
 bk_logger = logging.getLogger('blenderkit')
@@ -75,7 +75,7 @@ def check_errors(rdata):
 search_threads = []
 thumb_sml_download_threads = {}
 thumb_full_download_threads = {}
-reports = ''
+reports_queue = queue.Queue()
 
 rtips = ['Click or drag model or material in scene to link/append ',
          "Please rate responsively and plentifully. This helps us distribute rewards to the authors.",
@@ -412,9 +412,10 @@ def timer_update():
 
             wm[search_name] = []
 
-            global reports
-            if reports != '':
-                props.report = str(reports)
+            global reports_queue
+
+            while not reports_queue.empty():
+                props.report = str(reports_queue.get())
                 return .2
 
             rdata = thread[0].result
@@ -628,7 +629,7 @@ def generate_tooltip(mdata):
         t += 'Size: %s x %s x %sm\n' % (fmt_length(mparams['dimensionX']),
                                      fmt_length(mparams['dimensionY']),
                                      fmt_length(mparams['dimensionZ']))
-    if has(mparams, 'faceCount'):
+    if has(mparams, 'faceCount') and mdata['assetType'] == 'model':
         t += 'Face count: %s\n' % (mparams['faceCount'])
         # t += 'face count: %s, render: %s\n' % (mparams['faceCount'], mparams['faceCountRender'])
 
@@ -709,7 +710,7 @@ def generate_tooltip(mdata):
 
         show_rating_threshold = 5
 
-        if rcount < show_rating_threshold:
+        if rcount < show_rating_threshold and mdata['assetType'] != 'hdr':
             t += f"Only assets with enough ratings \nshow the rating value. Please rate.\n"
         if rc['quality'] >= show_rating_threshold:
             # t += f"{int(mdata['ratingsAverage']['quality']) * '*'}\n"
@@ -765,26 +766,6 @@ def generate_author_textblock(adata):
     return t
 
 
-def get_items_models(self, context):
-    global search_items_models
-    return search_items_models
-
-
-def get_items_brushes(self, context):
-    global search_items_brushes
-    return search_items_brushes
-
-
-def get_items_materials(self, context):
-    global search_items_materials
-    return search_items_materials
-
-
-def get_items_textures(self, context):
-    global search_items_textures
-    return search_items_textures
-
-
 class ThumbDownloader(threading.Thread):
     query = None
 
@@ -801,7 +782,12 @@ class ThumbDownloader(threading.Thread):
         return self._stop_event.is_set()
 
     def run(self):
-        r = rerequests.get(self.url, stream=False)
+        print('thumb downloader', self.url)
+        try:
+            r = requests.get(self.url, stream=False)
+        except Exception as e:
+            bk_logger.error('Thumbnail download failed')
+            bk_logger.error(str(e))
         if r.status_code == 200:
             with open(self.path, 'wb') as f:
                 f.write(r.content)
@@ -962,6 +948,11 @@ def query_to_url(query = {}, params = {}):
     urlquery = url + requeststring
     return urlquery
 
+def parse_html_formated_error(text):
+    report = text[text.find('<title>') + 7: text.find('</title>')]
+
+    return report
+
 class Searcher(threading.Thread):
     query = None
 
@@ -982,10 +973,12 @@ class Searcher(threading.Thread):
         return self._stop_event.is_set()
 
     def run(self):
+        global reports_queue
+
         maxthreads = 50
         query = self.query
         params = self.params
-        global reports
+
 
         t = time.time()
         mt('search thread started')
@@ -999,21 +992,21 @@ class Searcher(threading.Thread):
         try:
             utils.p(self.urlquery)
             r = rerequests.get(self.urlquery, headers=self.headers)  # , params = rparameters)
-            # print(r.url)
-            reports = ''
-            # utils.p(r.text)
         except requests.exceptions.RequestException as e:
             bk_logger.error(e)
-            reports = e
-            # props.report = e
+            reports_queue.put(str(e))
             return
+
         mt('search response is back ')
         try:
             rdata = r.json()
         except Exception as e:
-            reports = r.text
-            bk_logger.error(e)
+            error_description = parse_html_formated_error(r.text)
+            reports_queue.put(error_description)
+            tasks_queue.add_task((ui.add_report, (error_description, 10, colors.RED)))
 
+            bk_logger.error(e)
+            return
         mt('data parsed ')
         if not rdata.get('results'):
             utils.pprint(rdata)
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index 7969bea25594a30637f42be1ff26e038042d4c9f..7117055fa95de6390f2354e4af7decb9a62ea9a5 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -655,7 +655,10 @@ def draw_callback_2d_progress(self, context):
 
     for process in bg_blender.bg_processes:
         tcom = process[1]
-        draw_progress(x, y - index * 30, '%s' % tcom.lasttext,
+        n=''
+        if tcom.name is not None:
+            n = tcom.name +': '
+        draw_progress(x, y - index * 30, '%s' % n+tcom.lasttext,
                       tcom.progress)
         index += 1
     global reports
@@ -1873,6 +1876,11 @@ class AssetBarOperator(bpy.types.Operator):
 
         context.window_manager.modal_handler_add(self)
         ui_props.assetbar_on = True
+
+        #in an exceptional case these were accessed before  drag start.
+        self.drag_start_x = 0
+        self.drag_start_y = 0
+
         return {'RUNNING_MODAL'}
 
     def execute(self, context):
@@ -2151,6 +2159,9 @@ class RunAssetBarWithContext(bpy.types.Operator):
     bl_description = "Run assetbar with fixed context"
     bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
 
+    keep_running: BoolProperty(name="Keep Running", description='', default=True, options={'SKIP_SAVE'})
+    do_search: BoolProperty(name="Run Search", description='', default=False, options={'SKIP_SAVE'})
+
     # def modal(self, context, event):
     #     return {'RUNNING_MODAL'}
 
@@ -2159,11 +2170,11 @@ class RunAssetBarWithContext(bpy.types.Operator):
         if C_dict.get('window'):  # no 3d view, no asset bar.
             preferences = bpy.context.preferences.addons['blenderkit'].preferences
             if preferences.experimental_features:
-                bpy.ops.view3d.blenderkit_asset_bar_widget(C_dict, 'INVOKE_REGION_WIN', keep_running=True,
-                                                           do_search=False)
+                bpy.ops.view3d.blenderkit_asset_bar_widget(C_dict, 'INVOKE_REGION_WIN', keep_running=self.keep_running,
+                                                           do_search=self.do_search)
 
             else:
-                bpy.ops.view3d.blenderkit_asset_bar(C_dict, 'INVOKE_REGION_WIN', keep_running=True, do_search=False)
+                bpy.ops.view3d.blenderkit_asset_bar(C_dict, 'INVOKE_REGION_WIN', keep_running=self.keep_running, do_search=self.do_search)
         return {'FINISHED'}
 
 
@@ -2208,7 +2219,7 @@ def register_ui():
         return
     km = wm.keyconfigs.addon.keymaps.new(name="Window", space_type='EMPTY')
     # asset bar shortcut
-    kmi = km.keymap_items.new(AssetBarOperator.bl_idname, 'SEMI_COLON', 'PRESS', ctrl=False, shift=False)
+    kmi = km.keymap_items.new("object.run_assetbar_fix_context", 'SEMI_COLON', 'PRESS', ctrl=False, shift=False)
     kmi.properties.keep_running = False
     kmi.properties.do_search = False
     addon_keymapitems.append(kmi)
diff --git a/blenderkit/ui_bgl.py b/blenderkit/ui_bgl.py
index 2165cdc5dca3ad0249603386b26e62bf92566d4b..fabda329b1a7d9fa49dd778f5f169dbce41be798 100644
--- a/blenderkit/ui_bgl.py
+++ b/blenderkit/ui_bgl.py
@@ -77,6 +77,8 @@ def draw_rect_3d(coords, color):
 
 def draw_image(x, y, width, height, image, transparency, crop=(0, 0, 1, 1)):
     # draw_rect(x,y, width, height, (.5,0,0,.5))
+    if not image:
+        return;
 
     coords = [
         (x, y), (x + width, y),
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index 0dbeaf897aa4b357f9a584c7ed073b3457c7dbc3..6bacc895cf6070cf86f6eb6702a5e2d8162111f1 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -17,7 +17,8 @@
 # ##### END GPL LICENSE BLOCK #####
 
 
-from blenderkit import paths, ratings, utils, download, categories, icons, search, resolutions, ui
+from blenderkit import paths, ratings, utils, download, categories, icons, search, resolutions, ui, tasks_queue, \
+    autothumb
 
 from bpy.types import (
     Panel
@@ -35,8 +36,11 @@ from bpy.props import (
 import bpy
 import os
 import random
+import logging
 import blenderkit
 
+bk_logger = logging.getLogger('blenderkit')
+
 
 #   this was moved to separate interface:
 
@@ -153,6 +157,7 @@ def draw_upload_common(layout, props, asset_type, context):
         layout.prop(props, 'description')
         layout.prop(props, 'tags')
 
+
 def poll_local_panels():
     user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
     return user_preferences.panel_behaviour == 'BOTH' or user_preferences.panel_behaviour == 'LOCAL'
@@ -189,7 +194,6 @@ def draw_panel_hdr_upload(self, context):
         draw_upload_common(layout, props, 'HDR', context)
 
 
-
 def draw_panel_hdr_search(self, context):
     s = context.scene
     props = s.blenderkit_HDR
@@ -203,6 +207,15 @@ def draw_panel_hdr_search(self, context):
     utils.label_multiline(layout, text=props.report)
 
 
+
+def draw_thumbnail_upload_panel(layout, props):
+    update = False
+    tex = autothumb.get_texture_ui(props.thumbnail, '.upload_preview')
+    if not tex or not tex.image:
+        return
+    box = layout.box()
+    box.template_icon(icon_value=tex.image.preview.icon_id, scale=6.0)
+
 def draw_panel_model_upload(self, context):
     ob = bpy.context.active_object
     while ob.parent is not None:
@@ -216,6 +229,9 @@ def draw_panel_model_upload(self, context):
     col = layout.column()
     if props.is_generating_thumbnail:
         col.enabled = False
+
+    draw_thumbnail_upload_panel(col, props)
+
     prop_needed(col, props, 'thumbnail', props.thumbnail)
     if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
         col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE')
@@ -275,6 +291,8 @@ def draw_panel_scene_upload(self, context):
     col = layout.column()
     # if props.is_generating_thumbnail:
     #     col.enabled = False
+    draw_thumbnail_upload_panel(col, props)
+
     prop_needed(col, props, 'thumbnail', props.has_thumbnail, False)
     # if bpy.context.scene.render.engine == 'CYCLES':
     #     col.operator("object.blenderkit_generate_thumbnail", text='Generate thumbnail', icon='IMAGE_COL')
@@ -289,8 +307,6 @@ def draw_panel_scene_upload(self, context):
     # elif props.thumbnail_generating_state != '':
     #    utils.label_multiline(layout, text = props.thumbnail_generating_state)
 
-
-
     layout.prop(props, 'style')
     layout.prop(props, 'production_level')
     layout.prop(props, 'use_design_year')
@@ -621,15 +637,16 @@ def draw_panel_material_upload(self, context):
     draw_upload_common(layout, props, 'MATERIAL', context)
 
     # THUMBNAIL
-    row = layout.row()
+    row = layout.column()
     if props.is_generating_thumbnail:
         row.enabled = False
-    prop_needed(row, props, 'thumbnail', props.has_thumbnail, False)
 
+    draw_thumbnail_upload_panel(row, props)
 
+    prop_needed(row, props, 'thumbnail', props.has_thumbnail, False)
 
     if bpy.context.scene.render.engine in ('CYCLES', 'BLENDER_EEVEE'):
-        layout.operator("object.blenderkit_material_thumbnail", text='Render thumbnail with Cycles', icon='EXPORT')
+        layout.operator("object.blenderkit_generate_material_thumbnail", text='Render thumbnail with Cycles', icon='EXPORT')
     if props.is_generating_thumbnail:
         row = layout.row(align=True)
         row.label(text=props.thumbnail_generating_state, icon='RENDER_STILL')
@@ -653,8 +670,6 @@ def draw_panel_material_upload(self, context):
     layout.prop(props, 'animated')
     layout.prop(props, 'texture_size_meters')
 
-
-
     # tname = "." + bpy.context.active_object.active_material.name + "_thumbnail"
     # if props.has_thumbnail and bpy.data.textures.get(tname) is not None:
     #     row = layout.row()
@@ -971,15 +986,15 @@ class VIEW3D_PT_blenderkit_unified(Panel):
         if ui_props.asset_type_fold:
             expand_icon = 'TRIA_RIGHT'
         row = layout.row()
-        split = row.split(factor = 0.15)
-        split.prop(ui_props, 'asset_type_fold', icon = expand_icon, icon_only = True, emboss = False)
+        split = row.split(factor=0.15)
+        split.prop(ui_props, 'asset_type_fold', icon=expand_icon, icon_only=True, emboss=False)
 
         if ui_props.asset_type_fold:
             pass
-            #expanded interface with names in column
+            # expanded interface with names in column
             split = split.row()
             split.scale_x = 8
-            split.scale_y =1.6
+            split.scale_y = 1.6
             # split = row
             # split = layout.row()
         else:
@@ -1160,10 +1175,9 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
     # build search string from description and tags:
     op.keywords = asset_data['name']
     if asset_data.get('description'):
-        op.keywords += ' ' + asset_data.get('description')+' '
+        op.keywords += ' ' + asset_data.get('description') + ' '
     op.keywords += ' '.join(asset_data.get('tags'))
 
-
     if asset_data.get('canDownload') != 0:
         if len(bpy.context.selected_objects) > 0 and ui_props.asset_type == 'MODEL':
             aob = bpy.context.active_object
@@ -1228,7 +1242,7 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
                                                        0)  # str(utils.get_param(asset_data, 'textureResolutionMax'))
 
             elif asset_data['assetBaseId'] in s['assets used'].keys() and asset_data['assetType'] != 'hdr':
-                #HDRs are excluded from replacement, since they are always replaced.
+                # HDRs are excluded from replacement, since they are always replaced.
                 # called from asset bar:
                 print('context menu')
                 op = col.operator('scene.blenderkit_download', text='Replace asset resolution')
@@ -1287,6 +1301,16 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
             op.asset_id = asset_data['id']
             op.asset_type = asset_data['assetType']
 
+            if asset_data['assetType'] == 'model':
+                op = layout.operator('object.blenderkit_regenerate_thumbnail', text='Regenerate thumbnail')
+                op.asset_index = ui_props.active_index
+
+            if asset_data['assetType'] == 'material':
+                op = layout.operator('object.blenderkit_regenerate_material_thumbnail', text='Regenerate thumbnail')
+                op.asset_index = ui_props.active_index
+                # op.asset_id = asset_data['id']
+                # op.asset_type = asset_data['assetType']
+
         if author_id == str(profile['user']['id']):
             row = layout.row()
             row.operator_context = 'INVOKE_DEFAULT'
diff --git a/blenderkit/upload.py b/blenderkit/upload.py
index b2395f686ab01acaaa13fffb56115aadae145d72..cc72b92a66a9e4cb43d20b8010adb96854912eeb 100644
--- a/blenderkit/upload.py
+++ b/blenderkit/upload.py
@@ -659,6 +659,11 @@ class FastMetadata(bpy.types.Operator):
         update=update_free_full
     )
 
+
+    ####################
+
+
+
     @classmethod
     def poll(cls, context):
         scene = bpy.context.scene
@@ -739,6 +744,7 @@ class FastMetadata(bpy.types.Operator):
                 self.subcategory = cat_path[2]
         except Exception as e:
             print(e)
+
         self.message = f"Fast edit metadata of {asset_data['name']}"
         self.name = asset_data['displayName']
         self.description = asset_data['description']
diff --git a/blenderkit/upload_bg.py b/blenderkit/upload_bg.py
index 3307a72afe689cc971d66bb0cd8a83ae5e775992..1b91d51b8ba3205bbea34d495b45faea74d82280 100644
--- a/blenderkit/upload_bg.py
+++ b/blenderkit/upload_bg.py
@@ -93,8 +93,9 @@ def upload_file(upload_data, f):
                     uploaded = True
                     upload_done_url = paths.get_api_url() + 'uploads_s3/' + upload['id'] + '/upload-file/'
                     upload_response = rerequests.post(upload_done_url, headers=headers, verify=True)
-                    print(upload_response)
-                    tasks_queue.add_task((ui.add_report, (f"Finished file upload{os.path.basename(f['file_path'])}",)))
+                    # print(upload_response)
+                    # print(upload_response.text)
+                    tasks_queue.add_task((ui.add_report, (f"Finished file upload: {os.path.basename(f['file_path'])}",)))
                     return True
                 else:
                     print(upload_response.text)
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index 7abc07d581de888670e21ea8c357fe1142103441..953ded5e51bc994bd5f61554f041113d9564683f 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -326,14 +326,14 @@ def uploadable_asset_poll():
     return True
 
 
-def get_hidden_texture(img, force_reload=False):
-    # i = get_hidden_image(tpath, bdata_name, force_reload=force_reload)
-    # bdata_name = f".{bdata_name}"
-    t = bpy.data.textures.get(img.name)
+def get_hidden_texture(name, force_reload=False):
+    t = bpy.data.textures.get(name)
     if t is None:
-        t = bpy.data.textures.new(img.name, 'IMAGE')
-    if t.image != img:
-        t.image = img
+        t = bpy.data.textures.new(name, 'IMAGE')
+    if not t.image or t.image.name != name:
+        img = bpy.data.images.get(name)
+        if img:
+            t.image = img
     return t
 
 
@@ -691,15 +691,15 @@ def name_update(props):
         asset.name = fname
 
 
-def get_param(asset_data, parameter_name):
+def get_param(asset_data, parameter_name, default = None):
     if not asset_data.get('parameters'):
         # this can appear in older version files.
-        return None
+        return default
 
     for p in asset_data['parameters']:
         if p.get('parameterType') == parameter_name:
             return p['value']
-    return None
+    return default
 
 
 def params_to_dict(params):