finish make library conformation working
This commit is contained in:
		
							parent
							
								
									ab72a15a2c
								
							
						
					
					
						commit
						501cb460c8
					
				@ -22,6 +22,8 @@ if 'bpy' in locals():
 | 
				
			|||||||
    importlib.reload(rename_pose)
 | 
					    importlib.reload(rename_pose)
 | 
				
			||||||
    #importlib.reload(render_preview)
 | 
					    #importlib.reload(render_preview)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import bpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register():
 | 
					def register():
 | 
				
			||||||
    operators.register()
 | 
					    operators.register()
 | 
				
			||||||
    keymaps.register()
 | 
					    keymaps.register()
 | 
				
			||||||
 | 
				
			|||||||
@ -72,11 +72,11 @@ from asset_library.action.functions import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from asset_library.common.functions import (
 | 
					from asset_library.common.functions import (
 | 
				
			||||||
    #get_actionlib_dir,
 | 
					    #get_actionlib_dir,
 | 
				
			||||||
    get_asset_source,
 | 
					    #get_asset_source,
 | 
				
			||||||
    #get_catalog_path,
 | 
					    #get_catalog_path,
 | 
				
			||||||
    #read_catalog,
 | 
					    #read_catalog,
 | 
				
			||||||
    #set_actionlib_dir,
 | 
					    #set_actionlib_dir,
 | 
				
			||||||
    resync_lib,
 | 
					    #resync_lib,
 | 
				
			||||||
    get_active_library,
 | 
					    get_active_library,
 | 
				
			||||||
    get_active_catalog,
 | 
					    get_active_catalog,
 | 
				
			||||||
    asset_warning_callback
 | 
					    asset_warning_callback
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								action/preview.blend
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								action/preview.blend
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -3,7 +3,7 @@
 | 
				
			|||||||
from asset_library.common.bl_utils import get_addon_prefs, load_datablocks
 | 
					from asset_library.common.bl_utils import get_addon_prefs, load_datablocks
 | 
				
			||||||
from asset_library.common.file_utils import read_file, write_file
 | 
					from asset_library.common.file_utils import read_file, write_file
 | 
				
			||||||
from asset_library.common.template import Template
 | 
					from asset_library.common.template import Template
 | 
				
			||||||
from asset_library.constants import (PREVIEW_ASSETS_SCRIPT, MODULE_DIR)
 | 
					from asset_library.constants import (MODULE_DIR, RESOURCES_DIR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from asset_library import (action, collection, file)
 | 
					from asset_library import (action, collection, file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,48 +36,26 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        for lib in prefs.libraries:
 | 
					        for lib in prefs.libraries:
 | 
				
			||||||
            if lib.adapter == self:
 | 
					            if lib.adapter == self:
 | 
				
			||||||
                return lib
 | 
					                return lib
 | 
				
			||||||
            if lib.conform.adapter == self:
 | 
					 | 
				
			||||||
                return lib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #@property
 | 
					 | 
				
			||||||
    #def library_path(self):
 | 
					 | 
				
			||||||
    #    return self.library.library_path
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def is_conform(self):
 | 
					    def bundle_directory(self):
 | 
				
			||||||
        prefs = self.addon_prefs
 | 
					        return self.library.library_path
 | 
				
			||||||
        for lib in prefs.libraries:
 | 
					 | 
				
			||||||
            if lib.adapter == self:
 | 
					 | 
				
			||||||
                return False
 | 
					 | 
				
			||||||
            if lib.conform.adapter == self:
 | 
					 | 
				
			||||||
                return True 
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @property
 | 
					    # @property
 | 
				
			||||||
    def target_directory(self):
 | 
					    # def blend_depth(self):
 | 
				
			||||||
        if self.is_conform:
 | 
					    #     return self.library.blend_depth
 | 
				
			||||||
            return self.library.conform.directory
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        return self.library.bundle_directory
 | 
					    # @property
 | 
				
			||||||
 | 
					    # def template_image(self):
 | 
				
			||||||
 | 
					    #     return Template(self.library.template_image)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    # @property
 | 
				
			||||||
    def blend_depth(self):
 | 
					    # def template_video(self):
 | 
				
			||||||
        if self.is_conform:
 | 
					    #     return Template(self.library.template_video)
 | 
				
			||||||
            return self.library.conform.blend_depth
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return self.library.blend_depth
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_image(self):
 | 
					 | 
				
			||||||
        return Template(self.library.conform.template_image)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_video(self):
 | 
					 | 
				
			||||||
        return Template(self.library.conform.template_video)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_description(self):
 | 
					 | 
				
			||||||
        return Template(self.library.conform.template_description)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # @property
 | 
				
			||||||
 | 
					    # def template_description(self):
 | 
				
			||||||
 | 
					    #     return Template(self.library.template_description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def data_type(self):
 | 
					    def data_type(self):
 | 
				
			||||||
@ -87,21 +65,18 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
    def data_types(self):
 | 
					    def data_types(self):
 | 
				
			||||||
        return self.library.data_types
 | 
					        return self.library.data_types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #@property
 | 
					 | 
				
			||||||
    #def externalize_data(self):
 | 
					 | 
				
			||||||
    #    return self.library.externalize_data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #@property
 | 
					 | 
				
			||||||
    #def catalog_path(self):
 | 
					 | 
				
			||||||
    #    return self.library.catalog_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_catalog_path(self, directory=None):
 | 
					    def get_catalog_path(self, directory=None):
 | 
				
			||||||
        directory = directory or self.target_directory
 | 
					        directory = directory or self.bundle_directory
 | 
				
			||||||
        return Path(directory, 'blender_assets.cats.txt')
 | 
					        return Path(directory, 'blender_assets.cats.txt')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def cache_file(self):
 | 
					    def cache_file(self):
 | 
				
			||||||
        return Path(self.target_directory) / f"blender_assets.{self.library.id}.json"
 | 
					        return Path(self.bundle_directory) / f"blender_assets.{self.library.id}.json"
 | 
				
			||||||
 | 
					        #return get_asset_datas_file(self.library_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def tmp_cache_file(self):
 | 
				
			||||||
 | 
					        return Path(bpy.app.tempdir) / f"blender_assets.{self.library.id}.json"
 | 
				
			||||||
        #return get_asset_datas_file(self.library_path)
 | 
					        #return get_asset_datas_file(self.library_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
@ -149,22 +124,26 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        src = Path(source)
 | 
					        src = Path(source)
 | 
				
			||||||
        dst = Path(destination)
 | 
					        dst = Path(destination)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not source.exists():
 | 
					        if not src.exists():
 | 
				
			||||||
            print(f'Cannot copy file {source}: file not exist')
 | 
					            print(f'Cannot copy file {src}: file not exist')
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dst.parent.mkdir(exist_ok=True, parents=True)
 | 
					        dst.parent.mkdir(exist_ok=True, parents=True)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if src == dst:
 | 
					        if src == dst:
 | 
				
			||||||
            print(f'Cannot copy file {source}: source and destination are the same')
 | 
					            print(f'Cannot copy file {src}: source and destination are the same')
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(f'Copy file from {source} to {destination}')
 | 
					        print(f'Copy file from {src} to {dst}')
 | 
				
			||||||
        shutil.copy2(str(source), str(destination))
 | 
					        shutil.copy2(str(src), str(dst))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def load_datablocks(self, src, names=None, type='objects', link=True, expr=None):
 | 
					    def load_datablocks(self, src, names=None, type='objects', link=True, expr=None, assets_only=False):
 | 
				
			||||||
        """Link or append a datablock from a blendfile"""
 | 
					        """Link or append a datablock from a blendfile"""
 | 
				
			||||||
        return load_datablocks(src, names=names, type=type, link=link, expr=expr)
 | 
					
 | 
				
			||||||
 | 
					        if type.isupper():
 | 
				
			||||||
 | 
					            type = f'{type.lower()}s'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return load_datablocks(src, names=names, type=type, link=link, expr=expr, assets_only=assets_only)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_asset_relative_path(self, name, catalog):
 | 
					    def get_asset_relative_path(self, name, catalog):
 | 
				
			||||||
        '''Get a relative path for the asset'''
 | 
					        '''Get a relative path for the asset'''
 | 
				
			||||||
@ -220,7 +199,7 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            template = Path(asset_path, template).as_posix()
 | 
					            template = Path(asset_path, template).as_posix()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            'name': name,
 | 
					            'asset_name': name,
 | 
				
			||||||
            'asset_path': Path(asset_path),
 | 
					            'asset_path': Path(asset_path),
 | 
				
			||||||
            'catalog': catalog,
 | 
					            'catalog': catalog,
 | 
				
			||||||
            'catalog_name': catalog.replace('/', '_'),
 | 
					            'catalog_name': catalog.replace('/', '_'),
 | 
				
			||||||
@ -230,13 +209,13 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def get_description_path(self, name, asset_path, catalog) -> Path:
 | 
					    def get_description_path(self, name, asset_path, catalog) -> Path:
 | 
				
			||||||
        """"Get the path of the json or yaml describing all assets data in one file"""
 | 
					        """"Get the path of the json or yaml describing all assets data in one file"""
 | 
				
			||||||
        return self.get_template_path(self.library.conform.template_description, name, asset_path, catalog)
 | 
					        return self.get_template_path(self.library.template_description, name, asset_path, catalog)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_image_path(self, name, asset_path, catalog) -> Path:
 | 
					    def get_image_path(self, name, asset_path, catalog) -> Path:
 | 
				
			||||||
        return self.get_template_path(self.library.conform.template_image, name, asset_path, catalog)
 | 
					        return self.get_template_path(self.library.template_image, name, asset_path, catalog)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_video_path(self, name, asset_path, catalog) -> Path:
 | 
					    def get_video_path(self, name, asset_path, catalog) -> Path:
 | 
				
			||||||
        return self.get_template_path(self.library.conform.template_video, name, asset_path, catalog)
 | 
					        return self.get_template_path(self.library.template_video, name, asset_path, catalog)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    def get_path(self, type, name, asset_path, template=None) -> Path:
 | 
					    def get_path(self, type, name, asset_path, template=None) -> Path:
 | 
				
			||||||
@ -355,12 +334,13 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        print(f'Catalog writen at: {catalog_path}')
 | 
					        print(f'Catalog writen at: {catalog_path}')
 | 
				
			||||||
        catalog_path.write_text('\n'.join(lines), encoding="utf-8")
 | 
					        catalog_path.write_text('\n'.join(lines), encoding="utf-8")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def read_cache(self):
 | 
					    def read_cache(self, cache_path=None):
 | 
				
			||||||
        print(f'Read cache from {self.cache_file}')
 | 
					        cache_path = cache_path or self.cache_file
 | 
				
			||||||
        return self.read_file(self.cache_file)
 | 
					        print(f'Read cache from {cache_path}')
 | 
				
			||||||
 | 
					        return self.read_file(cache_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def write_cache(self, asset_descriptions):
 | 
					    def write_cache(self, asset_descriptions, cache_path=None):
 | 
				
			||||||
        cache_path = self.cache_file
 | 
					        cache_path = cache_path or self.cache_file
 | 
				
			||||||
        print(f'cache file writen to {cache_path}')
 | 
					        print(f'cache file writen to {cache_path}')
 | 
				
			||||||
        return write_file(cache_path, list(asset_descriptions))
 | 
					        return write_file(cache_path, list(asset_descriptions))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -408,7 +388,7 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        catalog_parts = asset_data['catalog'].split('/') + [asset_data['name']]
 | 
					        catalog_parts = asset_data['catalog'].split('/') + [asset_data['name']]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return catalog_parts[:self.blend_depth]
 | 
					        return catalog_parts[:self.library.blend_depth]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #def transfert_preview(self, )
 | 
					    #def transfert_preview(self, )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -463,10 +443,44 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    def generate_preview(self, asset_description):
 | 
					
 | 
				
			||||||
 | 
					    def generate_blend_preview(self, asset_description):
 | 
				
			||||||
 | 
					        asset_name = asset_description['name']
 | 
				
			||||||
 | 
					        catalog = asset_description['catalog']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        asset_path = self.format_path(asset_description['filepath'])
 | 
				
			||||||
 | 
					        dst_image_path = self.get_image_path(asset_name, asset_path, catalog)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if dst_image_path.exists():
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Check if a source image exists and if so copying it in the new directory
 | 
				
			||||||
 | 
					        src_image_path = asset_description.get('image')
 | 
				
			||||||
 | 
					        if src_image_path:
 | 
				
			||||||
 | 
					            src_image_path = self.get_template_path(src_image_path, asset_name, asset_path, catalog)
 | 
				
			||||||
 | 
					            if src_image_path and src_image_path.exists():
 | 
				
			||||||
 | 
					                self.copy_file(src_image_path, dst_image_path)
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print(f'Thumbnailing {asset_path} to {dst_image_path}')
 | 
				
			||||||
 | 
					        blender_thumbnailer = Path(bpy.app.binary_path).parent / 'blender-thumbnailer'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dst_image_path.parent.mkdir(exist_ok=True, parents=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        subprocess.call([blender_thumbnailer, str(asset_path), str(dst_image_path)])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        success = dst_image_path.exists()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not success:
 | 
				
			||||||
 | 
					            empty_preview = RESOURCES_DIR / 'empty_preview.png'
 | 
				
			||||||
 | 
					            self.copy_file(str(empty_preview), str(dst_image_path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def generate_asset_preview(self, asset_description):
 | 
				
			||||||
        """Only generate preview when conforming a library"""
 | 
					        """Only generate preview when conforming a library"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print('\ngenerate_preview', asset_description)
 | 
					        print('\ngenerate_preview', asset_description['filepath'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scn = bpy.context.scene
 | 
					        scn = bpy.context.scene
 | 
				
			||||||
        #Creating the preview for collection, object or material
 | 
					        #Creating the preview for collection, object or material
 | 
				
			||||||
@ -474,19 +488,28 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        vl = bpy.context.view_layer
 | 
					        vl = bpy.context.view_layer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data_type = self.data_type #asset_description['data_type']
 | 
					        data_type = self.data_type #asset_description['data_type']
 | 
				
			||||||
        asset_path = asset_description['filepath']
 | 
					        asset_path = self.format_path(asset_description['filepath'])
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        asset_data_names = {}
 | 
					        asset_data_names = {}
 | 
				
			||||||
        for asset_data in asset_description['assets']:
 | 
					        for asset_data in asset_description['assets']:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            name = asset_data['name']
 | 
					            name = asset_data['name']
 | 
				
			||||||
            catalog = asset_data['catalog']
 | 
					            catalog = asset_data['catalog']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            image_path = self.get_image_path(name, asset_path, catalog)
 | 
					            dst_image_path = self.get_image_path(name, asset_path, catalog)
 | 
				
			||||||
            if image_path.exists():
 | 
					            if dst_image_path.exists():
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            # Check if a source image exists and if so copying it in the new directory
 | 
				
			||||||
 | 
					            src_image_path = asset_data.get('image')
 | 
				
			||||||
 | 
					            if src_image_path:
 | 
				
			||||||
 | 
					                src_image_path = self.get_template_path(src_image_path, name, asset_path, catalog)
 | 
				
			||||||
 | 
					                if src_image_path and src_image_path.exists():
 | 
				
			||||||
 | 
					                    self.copy_file(src_image_path, dst_image_path)
 | 
				
			||||||
 | 
					                    return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #Store in a dict all asset_data that does not have preview
 | 
					            #Store in a dict all asset_data that does not have preview
 | 
				
			||||||
            asset_data_names[name] = dict(asset_data, image_path=image_path)
 | 
					            asset_data_names[name] = dict(asset_data, image_path=dst_image_path)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if not asset_data_names:
 | 
					        if not asset_data_names:
 | 
				
			||||||
            # No preview to generate
 | 
					            # No preview to generate
 | 
				
			||||||
@ -512,8 +535,6 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
                
 | 
					                
 | 
				
			||||||
                scn.render.filepath = str(image_path)
 | 
					                scn.render.filepath = str(image_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                print(f'Render asset {asset.name} to {image_path}')
 | 
					                print(f'Render asset {asset.name} to {image_path}')
 | 
				
			||||||
                bpy.ops.render.render(write_still=True)
 | 
					                bpy.ops.render.render(write_still=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -522,25 +543,27 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                bpy.data.objects.remove(instance)
 | 
					                bpy.data.objects.remove(instance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                #bpy.ops.object.delete(use_global=False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                #scn.collection.children.unlink(asset)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
 | 
					                bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def generate_previews(self, asset_descriptions=None):
 | 
					    def generate_previews(self, cache=None):
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        print('Generate previews')
 | 
					        print('Generate previews')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        asset_descriptions = asset_descriptions or self.fetch()
 | 
					        if cache in (None, ''):
 | 
				
			||||||
 | 
					            cache = self.fetch()
 | 
				
			||||||
 | 
					        elif isinstance(cache, (Path, str)):
 | 
				
			||||||
 | 
					            cache = self.read_cache(cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #cache_diff.sort(key=lambda x :x['filepath'])
 | 
					        #cache_diff.sort(key=lambda x :x['filepath'])
 | 
				
			||||||
        #blend_groups = groupby(cache_diff, key=lambda x :x['filepath'])
 | 
					        #blend_groups = groupby(cache_diff, key=lambda x :x['filepath'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #TODO Support all multiple data_type
 | 
					        #TODO Support all multiple data_type
 | 
				
			||||||
        for asset_description in asset_descriptions:
 | 
					        for asset_description in cache:
 | 
				
			||||||
            self.generate_preview(asset_description)
 | 
					
 | 
				
			||||||
 | 
					            if asset_description['type'] == 'FILE':
 | 
				
			||||||
 | 
					                self.generate_blend_preview(asset_description)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self.generate_asset_preview(asset_description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # filepath = asset_description['filepath']
 | 
					            # filepath = asset_description['filepath']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -561,7 +584,11 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
        asset_path = asset_data['filepath']
 | 
					        asset_path = asset_data['filepath']
 | 
				
			||||||
        catalog = asset_data['catalog']
 | 
					        catalog = asset_data['catalog']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        image_path = asset_data.get('image')
 | 
				
			||||||
 | 
					        if self.library.template_image:
 | 
				
			||||||
            image_path = self.get_image_path(name, asset_path, catalog)
 | 
					            image_path = self.get_image_path(name, asset_path, catalog)
 | 
				
			||||||
 | 
					        elif image_path:
 | 
				
			||||||
 | 
					            image_path = self.get_template_path(image_path, name, asset_path, catalog)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if image_path and image_path.exists():
 | 
					        if image_path and image_path.exists():
 | 
				
			||||||
            with bpy.context.temp_override(id=asset):
 | 
					            with bpy.context.temp_override(id=asset):
 | 
				
			||||||
@ -663,9 +690,6 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            print(f'{self.data_type} is not supported yet')
 | 
					            print(f'{self.data_type} is not supported yet')
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        target_dir = self.target_directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        catalog_data = self.read_catalog() #TODO remove unused catalog
 | 
					        catalog_data = self.read_catalog() #TODO remove unused catalog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        write_cache = False
 | 
					        write_cache = False
 | 
				
			||||||
@ -673,12 +697,15 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            # Get list of all modifications
 | 
					            # Get list of all modifications
 | 
				
			||||||
            asset_descriptions = self.fetch()
 | 
					            asset_descriptions = self.fetch()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cache, cache_diff = self.diff(asset_descriptions)
 | 
					            cache, cache_diff = self.diff(asset_descriptions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Only write complete cache at the end
 | 
					            # Only write complete cache at the end
 | 
				
			||||||
            write_cache = True
 | 
					            write_cache = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.generate_previews(asset_descriptions)
 | 
					            #self.generate_previews(asset_descriptions)
 | 
				
			||||||
 | 
					            self.write_cache(asset_descriptions, self.tmp_cache_file)
 | 
				
			||||||
 | 
					            bpy.ops.assetlib.generate_previews(name=self.library.name, cache=str(self.tmp_cache_file))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #print()
 | 
					            #print()
 | 
				
			||||||
            #print(cache)
 | 
					            #print(cache)
 | 
				
			||||||
@ -688,7 +715,7 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            cache_diff = json.loads(Path(cache_diff).read_text(encoding='utf-8'))
 | 
					            cache_diff = json.loads(Path(cache_diff).read_text(encoding='utf-8'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.blend_depth == 0:
 | 
					        if self.library.blend_depth == 0:
 | 
				
			||||||
            raise Exception('Blender depth must be 1 at min')
 | 
					            raise Exception('Blender depth must be 1 at min')
 | 
				
			||||||
            #groups = [(cache_diff)]
 | 
					            #groups = [(cache_diff)]
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
@ -702,11 +729,14 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            print('No assets found')
 | 
					            print('No assets found')
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #data_types = self.data_types
 | 
				
			||||||
 | 
					        #if self.data_types == 'FILE'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        i = 0
 | 
					        i = 0
 | 
				
			||||||
        #assets_to_preview = []
 | 
					        #assets_to_preview = []
 | 
				
			||||||
        for sub_path, asset_datas in groups:
 | 
					        for sub_path, asset_datas in groups:
 | 
				
			||||||
            blend_name = sub_path[-1].replace(' ', '_').lower()
 | 
					            blend_name = sub_path[-1].replace(' ', '_').lower()
 | 
				
			||||||
            blend_path = Path(target_dir, *sub_path, blend_name).with_suffix('.blend')
 | 
					            blend_path = Path(self.bundle_directory, *sub_path, blend_name).with_suffix('.blend')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if blend_path.exists():
 | 
					            if blend_path.exists():
 | 
				
			||||||
                print(f'Opening existing bundle blend: {blend_path}')
 | 
					                print(f'Opening existing bundle blend: {blend_path}')
 | 
				
			||||||
@ -768,7 +798,6 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
            print(f'Saving Blend to {blend_path}')
 | 
					            print(f'Saving Blend to {blend_path}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            blend_path.parent.mkdir(exist_ok=True, parents=True)
 | 
					            blend_path.parent.mkdir(exist_ok=True, parents=True)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            bpy.ops.wm.save_as_mainfile(filepath=str(blend_path), compress=True)
 | 
					            bpy.ops.wm.save_as_mainfile(filepath=str(blend_path), compress=True)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if write_cache:
 | 
					        if write_cache:
 | 
				
			||||||
@ -847,8 +876,8 @@ class AssetLibraryAdapter(PropertyGroup):
 | 
				
			|||||||
    def format_path(self, template, **kargs):
 | 
					    def format_path(self, template, **kargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        params = dict(
 | 
					        params = dict(
 | 
				
			||||||
            bundle_dir=Path(self.library.bundle_directory),
 | 
					            bundle_dir=Path(self.bundle_directory),
 | 
				
			||||||
            conform_dir=Path(self.library.conform.directory),
 | 
					            #conform_dir=Path(self.library.conform.directory),
 | 
				
			||||||
            **kargs,
 | 
					            **kargs,
 | 
				
			||||||
            **self.to_dict(), 
 | 
					            **self.to_dict(), 
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ from asset_library.adapters.adapter import AssetLibraryAdapter
 | 
				
			|||||||
from asset_library.common.file_utils import copy_dir
 | 
					from asset_library.common.file_utils import copy_dir
 | 
				
			||||||
from bpy.props import StringProperty
 | 
					from bpy.props import StringProperty
 | 
				
			||||||
from os.path import expandvars
 | 
					from os.path import expandvars
 | 
				
			||||||
 | 
					import bpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CopyFolderLibrary(AssetLibraryAdapter):
 | 
					class CopyFolderLibrary(AssetLibraryAdapter):
 | 
				
			||||||
@ -21,7 +22,7 @@ class CopyFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def bundle(self, cache_diff=None):
 | 
					    def bundle(self, cache_diff=None):
 | 
				
			||||||
        src = expandvars(self.source_directory)
 | 
					        src = expandvars(self.source_directory)
 | 
				
			||||||
        dst = expandvars(self.target_directory)
 | 
					        dst = expandvars(self.bundle_directory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        includes = [inc.strip() for inc in self.includes.split(',')]
 | 
					        includes = [inc.strip() for inc in self.includes.split(',')]
 | 
				
			||||||
        excludes = [ex.strip() for ex in self.excludes.split(',')]
 | 
					        excludes = [ex.strip() for ex in self.excludes.split(',')]
 | 
				
			||||||
@ -32,3 +33,14 @@ class CopyFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
            excludes=excludes, includes=includes
 | 
					            excludes=excludes, includes=includes
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    def filter_prop(self, prop):
 | 
				
			||||||
 | 
					        if prop in ('template_description', 'template_video', 'template_image', 'blend_depth'):
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # def draw_prop(self, layout, prop):
 | 
				
			||||||
 | 
					    #     if prop in ('template_description', 'template_video', 'template_image', 'blend_depth'):
 | 
				
			||||||
 | 
					    #         return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #     super().draw_prop(layout)
 | 
				
			||||||
@ -28,6 +28,7 @@ class KitsuLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
    template_name : StringProperty()
 | 
					    template_name : StringProperty()
 | 
				
			||||||
    template_file : StringProperty()
 | 
					    template_file : StringProperty()
 | 
				
			||||||
    source_directory : StringProperty(subtype='DIR_PATH')
 | 
					    source_directory : StringProperty(subtype='DIR_PATH')
 | 
				
			||||||
 | 
					    #blend_depth: IntProperty(default=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    url: StringProperty()
 | 
					    url: StringProperty()
 | 
				
			||||||
    login: StringProperty()
 | 
					    login: StringProperty()
 | 
				
			||||||
@ -83,8 +84,8 @@ class KitsuLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
                description=data['description'],
 | 
					                description=data['description'],
 | 
				
			||||||
                tags=[],
 | 
					                tags=[],
 | 
				
			||||||
                type=self.data_type,
 | 
					                type=self.data_type,
 | 
				
			||||||
                image=self.template_image.raw,
 | 
					                image=self.library.template_image,
 | 
				
			||||||
                video=self.template_video.raw,
 | 
					                video=self.library.template_video,
 | 
				
			||||||
                name=data['name'])
 | 
					                name=data['name'])
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
@ -96,16 +97,6 @@ class KitsuLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    #     return super().bundle(cache_diff=cache_diff)
 | 
					    #     return super().bundle(cache_diff=cache_diff)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def get_preview(self, asset_data):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        name = asset_data['name']
 | 
					 | 
				
			||||||
        preview = (f / template_image.format(name=name)).resolve()
 | 
					 | 
				
			||||||
        if not preview.exists():
 | 
					 | 
				
			||||||
            preview_blend_file(f, preview)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return preview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    def fetch(self):
 | 
					    def fetch(self):
 | 
				
			||||||
        """Gather in a list all assets found in the folder"""
 | 
					        """Gather in a list all assets found in the folder"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,11 +113,11 @@ class KitsuLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
        entity_types_ids = {e['id']: e['name'] for e in entity_types}
 | 
					        entity_types_ids = {e['id']: e['name'] for e in entity_types}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        asset_descriptions = []
 | 
					        asset_descriptions = []
 | 
				
			||||||
        for asset_data in gazu.asset.all_assets_for_project(project)[:10]:
 | 
					        for asset_data in gazu.asset.all_assets_for_project(project):
 | 
				
			||||||
            asset_data['entity_type_name'] = entity_types_ids[asset_data.pop('entity_type_id')]
 | 
					            asset_data['entity_type_name'] = entity_types_ids[asset_data.pop('entity_type_id')]
 | 
				
			||||||
            asset_name = asset_data['name']
 | 
					            asset_name = asset_data['name']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            asset_field_data = dict(name=asset_name, type=asset_data['entity_type_name'], source_directory=self.source_directory)
 | 
					            asset_field_data = dict(asset_name=asset_name, type=asset_data['entity_type_name'], source_directory=self.source_directory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                asset_field_data.update(template_name.parse(asset_name))
 | 
					                asset_field_data.update(template_name.parse(asset_name))
 | 
				
			||||||
@ -140,6 +131,7 @@ class KitsuLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            #print(asset_path)
 | 
					            #print(asset_path)
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            # TODO group when multiple asset are store in the same blend
 | 
				
			||||||
            asset_descriptions.append(self.get_asset_description(asset_data, asset_path))
 | 
					            asset_descriptions.append(self.get_asset_description(asset_data, asset_path))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #asset = load_datablocks(asset_path, data_type='collections', names=asset_data['name'], link=True)
 | 
					            #asset = load_datablocks(asset_path, data_type='collections', names=asset_data['name'], link=True)
 | 
				
			||||||
 | 
				
			|||||||
@ -23,8 +23,11 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    name = "Scan Folder"
 | 
					    name = "Scan Folder"
 | 
				
			||||||
    source_directory : StringProperty(subtype='DIR_PATH')
 | 
					    source_directory : StringProperty(subtype='DIR_PATH')
 | 
				
			||||||
    template : StringProperty()
 | 
					    template_file : StringProperty()
 | 
				
			||||||
    blend_depth : IntProperty()
 | 
					    template_image : StringProperty()
 | 
				
			||||||
 | 
					    template_video : StringProperty()
 | 
				
			||||||
 | 
					    template_description : StringProperty()
 | 
				
			||||||
 | 
					    #blend_depth : IntProperty()
 | 
				
			||||||
    #externalize_preview : BoolProperty(default=True)
 | 
					    #externalize_preview : BoolProperty(default=True)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    #def draw_header(self, layout):
 | 
					    #def draw_header(self, layout):
 | 
				
			||||||
@ -38,6 +41,7 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
        directory = directory or self.source_directory
 | 
					        directory = directory or self.source_directory
 | 
				
			||||||
        return Path(directory, self.get_asset_relative_path(name, catalog))
 | 
					        return Path(directory, self.get_asset_relative_path(name, catalog))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
    def get_asset_description(self, asset, catalog, modified):
 | 
					    def get_asset_description(self, asset, catalog, modified):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        asset_path = self.get_asset_relative_path(name=asset.name, catalog=catalog)
 | 
					        asset_path = self.get_asset_relative_path(name=asset.name, catalog=catalog)
 | 
				
			||||||
@ -61,6 +65,38 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return asset_description
 | 
					        return asset_description
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_asset_description(self, data, asset_path):
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        asset_path = self.prop_rel_path(asset_path, 'source_directory')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.data_type == 'FILE':
 | 
				
			||||||
 | 
					            return dict(
 | 
				
			||||||
 | 
					                filepath=asset_path,
 | 
				
			||||||
 | 
					                modified=data['modified'],
 | 
				
			||||||
 | 
					                catalog=data['catalog'],
 | 
				
			||||||
 | 
					                tags=[],
 | 
				
			||||||
 | 
					                type=self.data_type,
 | 
				
			||||||
 | 
					                image=self.template_image,
 | 
				
			||||||
 | 
					                name=data['name']
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return dict(
 | 
				
			||||||
 | 
					            filepath=asset_path,
 | 
				
			||||||
 | 
					            modified=data['modified'],
 | 
				
			||||||
 | 
					            library_id=self.library.id,
 | 
				
			||||||
 | 
					            assets=[dict(
 | 
				
			||||||
 | 
					                catalog=asset_data['catalog'],
 | 
				
			||||||
 | 
					                metadata=asset_data.get('metadata', {}),
 | 
				
			||||||
 | 
					                description=asset_data.get('description'),
 | 
				
			||||||
 | 
					                tags=asset_data.get('tags', []),
 | 
				
			||||||
 | 
					                type=self.data_type,
 | 
				
			||||||
 | 
					                image=self.template_image,
 | 
				
			||||||
 | 
					                video=self.template_video,
 | 
				
			||||||
 | 
					                name=asset_data['name']) for asset_data in data['assets']
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _find_blend_files(self):
 | 
					    def _find_blend_files(self):
 | 
				
			||||||
        '''Get a sorted list of all blender files found matching the template'''
 | 
					        '''Get a sorted list of all blender files found matching the template'''
 | 
				
			||||||
@ -76,6 +112,7 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return blend_files
 | 
					        return blend_files
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
    def _group_key(self, asset_data):
 | 
					    def _group_key(self, asset_data):
 | 
				
			||||||
        """Group assets inside one blend"""
 | 
					        """Group assets inside one blend"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -238,17 +275,9 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
        self.write_catalog(catalog_data)
 | 
					        self.write_catalog(catalog_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bpy.ops.wm.quit_blender()
 | 
					        bpy.ops.wm.quit_blender()
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_preview(self, asset_data):
 | 
					    '''
 | 
				
			||||||
 | 
					 | 
				
			||||||
        name = asset_data['name']
 | 
					 | 
				
			||||||
        preview = (f / template_image.format(name=name)).resolve()
 | 
					 | 
				
			||||||
        if not preview.exists():
 | 
					 | 
				
			||||||
            preview_blend_file(f, preview)
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return preview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def conform(self, directory, templates):
 | 
					    def conform(self, directory, templates):
 | 
				
			||||||
        """Split each assets per blend and externalize preview"""
 | 
					        """Split each assets per blend and externalize preview"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -317,20 +346,20 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
                    self.copy_file(src_video_path, dst_video_path)
 | 
					                    self.copy_file(src_video_path, dst_video_path)
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        self.write_catalog(catalog_data, filepath=directory)
 | 
					        self.write_catalog(catalog_data, filepath=directory)
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
    def fetch(self):
 | 
					    def fetch(self):
 | 
				
			||||||
        """Gather in a list all assets found in the folder"""
 | 
					        """Gather in a list all assets found in the folder"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(f'Fetch Assets for {self.library.name}')
 | 
					        print(f'Fetch Assets for {self.library.name}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        source_directory = Path(os.path.expandvars(self.source_directory))
 | 
					        source_directory = Path(self.source_directory)
 | 
				
			||||||
        template = Template(self.template)
 | 
					        template_file = Template(self.template_file)
 | 
				
			||||||
        catalog_data = self.read_catalog(filepath=source_directory)
 | 
					        catalog_data = self.read_catalog(directory=source_directory)
 | 
				
			||||||
        catalog_ids = {v['id']: {'path': k, 'name': v['name']} for k,v in catalog_data.items()}
 | 
					        catalog_ids = {v['id']: k for k, v in catalog_data.items()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cache = self.read_cache() or []
 | 
					        cache = self.read_cache() or []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(f'Search for blend using glob template: {template.glob_pattern}')
 | 
					        print(f'Search for blend using glob template: {template_file.glob_pattern}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(f'Scanning Folder {source_directory}...')
 | 
					        print(f'Scanning Folder {source_directory}...')
 | 
				
			||||||
        #blend_files = list(source_directory.glob(template.glob_pattern))
 | 
					        #blend_files = list(source_directory.glob(template.glob_pattern))
 | 
				
			||||||
@ -344,103 +373,72 @@ class ScanFolderLibrary(AssetLibraryAdapter):
 | 
				
			|||||||
        #blend_paths = []
 | 
					        #blend_paths = []
 | 
				
			||||||
        new_cache = []
 | 
					        new_cache = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for blend_file in template.glob(source_directory):#sorted(blend_files):
 | 
					        for asset_path in template_file.glob(source_directory):#sorted(blend_files):
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            source_rel_path = self.prop_rel_path(blend_file, 'source_directory')
 | 
					            source_rel_path = self.prop_rel_path(asset_path, 'source_directory')
 | 
				
			||||||
            modified = blend_file.stat().st_mtime_ns
 | 
					            modified = asset_path.stat().st_mtime_ns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Check if the asset description as already been cached
 | 
				
			||||||
            asset_description = next((a for a in cache if a['filepath'] == source_rel_path), None)
 | 
					            asset_description = next((a for a in cache if a['filepath'] == source_rel_path), None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if asset_description and asset_description['modified'] >= modified:
 | 
					            if asset_description and asset_description['modified'] >= modified:
 | 
				
			||||||
                print(blend_file, 'is skipped because not modified')
 | 
					                print(asset_path, 'is skipped because not modified')
 | 
				
			||||||
                new_cache.append(asset_description)
 | 
					                new_cache.append(asset_description)
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            rel_path = blend_file.relative_to(source_directory).as_posix()
 | 
					            rel_path = asset_path.relative_to(source_directory).as_posix()
 | 
				
			||||||
            #field_values = re.findall(re_pattern, rel_path)[0]
 | 
					            field_data = template_file.parse(rel_path)
 | 
				
			||||||
            #field_data = {k:v for k,v in zip(field_names, field_values)}
 | 
					 | 
				
			||||||
            field_data = template.parse(rel_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if not field_data:
 | 
					 | 
				
			||||||
                raise Exception()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            #asset_data = (blend_file / prefs.template_description.format(name=name)).resolve()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            catalogs = [v for k,v in sorted(field_data.items()) if k.isdigit()]
 | 
					            catalogs = [v for k,v in sorted(field_data.items()) if k.isdigit()]
 | 
				
			||||||
            catalogs = [c.replace('_', ' ').title() for c in catalogs]
 | 
					            catalogs = [c.replace('_', ' ').title() for c in catalogs]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            asset_datas = {
 | 
				
			||||||
 | 
					                "name": field_data['asset_name'],
 | 
				
			||||||
 | 
					                "catalog": '/'.join(catalogs),
 | 
				
			||||||
 | 
					                "assets": [],
 | 
				
			||||||
 | 
					                'modified': modified
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if self.data_type == 'FILE':
 | 
					            if self.data_type == 'FILE':
 | 
				
			||||||
                name = field_data.get('name', blend_file.stem)
 | 
					                asset_description = self.get_asset_description(asset_datas, asset_path)
 | 
				
			||||||
                image = self.get_path('image', name=name, asset_path=blend_file)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                asset_description = dict(
 | 
					 | 
				
			||||||
                    filepath=source_rel_path,
 | 
					 | 
				
			||||||
                    modified=modified,
 | 
					 | 
				
			||||||
                    catalog='/'.join(catalogs),
 | 
					 | 
				
			||||||
                    tags=[],
 | 
					 | 
				
			||||||
                    type=self.data_type,
 | 
					 | 
				
			||||||
                    image=self.prop_rel_path(image, 'source_directory'),
 | 
					 | 
				
			||||||
                    name=name
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                new_cache.append(asset_description)
 | 
					                new_cache.append(asset_description)
 | 
				
			||||||
 | 
					 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #First Check if there is a asset_data .json
 | 
					            # Now check if there is a asset description file
 | 
				
			||||||
            asset_description = self.read_asset_description_file(blend_file)
 | 
					            asset_description_path = self.get_template_path(
 | 
				
			||||||
 | 
					                self.template_description,
 | 
				
			||||||
 | 
					                asset_datas['asset_name'],
 | 
				
			||||||
 | 
					                asset_path,
 | 
				
			||||||
 | 
					                asset_datas['catalog'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if asset_description_path and asset_description_path.exists():
 | 
				
			||||||
 | 
					                new_cache.append(self.read_file(asset_description_path))
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if not asset_description:
 | 
					 | 
				
			||||||
            # Scan the blend file for assets inside and write a custom asset description for info found
 | 
					            # Scan the blend file for assets inside and write a custom asset description for info found
 | 
				
			||||||
 | 
					            print(f'Scanning blendfile {asset_path}...')
 | 
				
			||||||
                print(f'Scanning blendfile {blend_file}...')
 | 
					            assets = self.load_datablocks(asset_path, type=self.data_types, link=True, assets_only=True)
 | 
				
			||||||
                with bpy.data.libraries.load(str(blend_file), link=True, assets_only=True) as (data_from, data_to):
 | 
					            print(f'Found {len(assets)} {self.data_types} inside')
 | 
				
			||||||
                    asset_names = getattr(data_from, self.data_types)
 | 
					 | 
				
			||||||
                    print(f'Found {len(asset_names)} {self.data_types} inside')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    setattr(data_to, self.data_types, asset_names)
 | 
					 | 
				
			||||||
                    assets = getattr(data_to, self.data_types)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                asset_description = dict(
 | 
					 | 
				
			||||||
                    filepath=source_rel_path,
 | 
					 | 
				
			||||||
                    modified=modified,
 | 
					 | 
				
			||||||
                    assets=[]
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for asset in assets:
 | 
					            for asset in assets:
 | 
				
			||||||
                    asset_catalog_data = catalog_ids.get(asset.asset_data.catalog_id)
 | 
					                catalog_path = catalog_ids.get(asset.asset_data.catalog_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if not asset_catalog_data:
 | 
					                if not catalog_path:
 | 
				
			||||||
                    print(f'No catalog found for asset {asset.name}')
 | 
					                    print(f'No catalog found for asset {asset.name}')
 | 
				
			||||||
                        asset_catalog_data = {"path": blend_file.relative_to(self.source_directory).as_posix()}
 | 
					                    catalog_path = asset_path.relative_to(self.source_directory).as_posix()
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                    catalog_path = asset_catalog_data['path']
 | 
					                asset_datas['assets'] += [dict(
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    image_path = self.get_path('image', asset.name, catalog_path)
 | 
					 | 
				
			||||||
                    image = self.prop_rel_path(image_path, 'source_directory')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    # Write image only if no image was found
 | 
					 | 
				
			||||||
                    if not image_path.exists():
 | 
					 | 
				
			||||||
                        image_path = self.get_cache_image_path(asset.name, catalog_path)
 | 
					 | 
				
			||||||
                        image = self.prop_rel_path(image_path, 'library_path')
 | 
					 | 
				
			||||||
                        self.write_preview(asset.preview, image_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    video_path = self.get_path('video', asset.name, catalog_path)
 | 
					 | 
				
			||||||
                    video = self.prop_rel_path(video_path, 'source_directory')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    asset_data = dict(
 | 
					 | 
				
			||||||
                        filepath=self.prop_rel_path(blend_file, 'source_directory'),
 | 
					 | 
				
			||||||
                        modified=modified,
 | 
					 | 
				
			||||||
                    catalog=catalog_path,
 | 
					                    catalog=catalog_path,
 | 
				
			||||||
                    tags=asset.asset_data.tags.keys(),
 | 
					                    tags=asset.asset_data.tags.keys(),
 | 
				
			||||||
 | 
					                    metadata=dict(asset.asset_data),
 | 
				
			||||||
                    type=self.data_type,
 | 
					                    type=self.data_type,
 | 
				
			||||||
                        image=image,
 | 
					 | 
				
			||||||
                        video=video,
 | 
					 | 
				
			||||||
                    name=asset.name
 | 
					                    name=asset.name
 | 
				
			||||||
                    )
 | 
					                )]
 | 
				
			||||||
                    asset_description['assets'].append(asset_data)
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
                getattr(bpy.data, self.data_types).remove(asset)
 | 
					                getattr(bpy.data, self.data_types).remove(asset)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            asset_description = self.get_asset_description(asset_datas, asset_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            new_cache.append(asset_description)
 | 
					            new_cache.append(asset_description)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ if 'bpy' in locals():
 | 
				
			|||||||
    #importlib.reload(build_collection_blends)
 | 
					    #importlib.reload(build_collection_blends)
 | 
				
			||||||
    #importlib.reload(create_collection_library)
 | 
					    #importlib.reload(create_collection_library)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import bpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register():
 | 
					def register():
 | 
				
			||||||
    operators.register()
 | 
					    operators.register()
 | 
				
			||||||
 | 
				
			|||||||
@ -42,43 +42,29 @@ class ASSETLIB_OT_load_asset(Operator):
 | 
				
			|||||||
        print('Load Asset')
 | 
					        print('Load Asset')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        lib = get_active_library()
 | 
					        lib = get_active_library()
 | 
				
			||||||
        print(lib, lib.data_type)
 | 
					 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
        # dir(asset) :  'asset_data', 'bl_rna', 'id_type', 'local_id', 'name', 'preview_icon_id', 'relative_path', 'rna_type']
 | 
					 | 
				
			||||||
        # dir(asset.asset_data) : 'active_tag', 'author', 'bl_rna', 'catalog_id', 'catalog_simple_name', 'description', 'rna_type', 'tags']
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ## get source path
 | 
					 | 
				
			||||||
        # asset_file_handle = context.asset_file_handle
 | 
					 | 
				
			||||||
        # if asset_file_handle is None:
 | 
					 | 
				
			||||||
        #     return {'CANCELLED'}
 | 
					 | 
				
			||||||
        # if asset_file_handle.local_id:
 | 
					 | 
				
			||||||
        #     return {'CANCELLED'}
 | 
					 | 
				
			||||||
        # asset_library_ref = context.asset_library_ref
 | 
					 | 
				
			||||||
        # source_directory = bpy.types.AssetHandle.get_full_library_path(
 | 
					 | 
				
			||||||
        #     asset_file_handle, asset_library_ref
 | 
					 | 
				
			||||||
        # )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        asset = context.active_file
 | 
					        asset = context.active_file
 | 
				
			||||||
        if not asset:
 | 
					        if not asset:
 | 
				
			||||||
            self.report({"ERROR"}, 'No asset selected')
 | 
					            self.report({"ERROR"}, 'No asset selected')
 | 
				
			||||||
            return {'CANCELLED'}
 | 
					            return {'CANCELLED'}
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        active_lib = lib.adapter.get_active_asset_library()
 | 
				
			||||||
        asset_path = asset.asset_data['filepath']
 | 
					        asset_path = asset.asset_data['filepath']
 | 
				
			||||||
        fp = lib.adapter.format_path(asset_path)
 | 
					        asset_path = active_lib.adapter.format_path(asset_path)
 | 
				
			||||||
        name = asset.name
 | 
					        name = asset.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ## set mode to object
 | 
					        ## set mode to object
 | 
				
			||||||
        if context.mode != 'OBJECT':
 | 
					        if context.mode != 'OBJECT':
 | 
				
			||||||
            bpy.ops.object.mode_set(mode='OBJECT')
 | 
					            bpy.ops.object.mode_set(mode='OBJECT')
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        ## get the real direct path with expand_var
 | 
					        if not Path(asset_path).exists():
 | 
				
			||||||
        print('path expanded: ', fp)
 | 
					            self.report({'ERROR'}, f'Not exists: {asset_path}')
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not Path(fp).exists():
 | 
					 | 
				
			||||||
            self.report({'ERROR'}, f'Not exists: {fp}')
 | 
					 | 
				
			||||||
            return {'CANCELLED'}
 | 
					            return {'CANCELLED'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res = load_col(fp, name, link=True, override=True, rig_pattern='*_rig')
 | 
					        print('Load collection', asset_path, name)
 | 
				
			||||||
 | 
					        res = load_col(asset_path, name, link=True, override=True, rig_pattern='*_rig')
 | 
				
			||||||
        if res:
 | 
					        if res:
 | 
				
			||||||
            if res.type == 'ARMATURE':
 | 
					            if res.type == 'ARMATURE':
 | 
				
			||||||
                self.report({'INFO'}, f'Override rig {res.name}')
 | 
					                self.report({'INFO'}, f'Override rig {res.name}')
 | 
				
			||||||
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							@ -13,6 +13,7 @@ from bpy_extras import asset_utils
 | 
				
			|||||||
from asset_library.constants import RESOURCES_DIR
 | 
					from asset_library.constants import RESOURCES_DIR
 | 
				
			||||||
#from asset_library.common.file_utils import no
 | 
					#from asset_library.common.file_utils import no
 | 
				
			||||||
from os.path import abspath
 | 
					from os.path import abspath
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class attr_set():
 | 
					class attr_set():
 | 
				
			||||||
@ -328,13 +329,10 @@ def split_path(path) :
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def load_datablocks(src, names=None, type='objects', link=True, expr=None) -> list:
 | 
					def load_datablocks(src, names=None, type='objects', link=True, expr=None, assets_only=False) -> list:
 | 
				
			||||||
    return_list = not isinstance(names, str)
 | 
					    return_list = not isinstance(names, str)
 | 
				
			||||||
    names = names or []
 | 
					    names = names or []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if type.isupper():
 | 
					 | 
				
			||||||
        type = f'{type.lower()}s'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if not isinstance(names, (list, tuple)):
 | 
					    if not isinstance(names, (list, tuple)):
 | 
				
			||||||
        names = [names]
 | 
					        names = [names]
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@ -342,7 +340,7 @@ def load_datablocks(src, names=None, type='objects', link=True, expr=None) -> li
 | 
				
			|||||||
        pattern = expr
 | 
					        pattern = expr
 | 
				
			||||||
        expr = lambda x : fnmatch(x, pattern)
 | 
					        expr = lambda x : fnmatch(x, pattern)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    with bpy.data.libraries.load(str(src), link=link) as (data_from, data_to):
 | 
					    with bpy.data.libraries.load(str(src), link=link,assets_only=assets_only) as (data_from, data_to):
 | 
				
			||||||
        datablocks = getattr(data_from, type)
 | 
					        datablocks = getattr(data_from, type)
 | 
				
			||||||
        if expr:
 | 
					        if expr:
 | 
				
			||||||
            names += [i for i in datablocks if expr(i)]
 | 
					            names += [i for i in datablocks if expr(i)]
 | 
				
			||||||
@ -384,13 +382,7 @@ def load_col(filepath, name, link=True, override=True, rig_pattern=None, context
 | 
				
			|||||||
    # return data_to.collections[0]
 | 
					    # return data_to.collections[0]
 | 
				
			||||||
    context = context or bpy.context
 | 
					    context = context or bpy.context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    collections = load_datablocks(filepath, name, link=link, type='collections')
 | 
					    col = load_datablocks(filepath, name, link=link, type='collections')
 | 
				
			||||||
    if not collections:
 | 
					 | 
				
			||||||
        print(f'No collection "{name}" found in: {filepath}')
 | 
					 | 
				
			||||||
        return
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    col = collections[0]
 | 
					 | 
				
			||||||
    print('collection:', col.name)
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    ## create instance object
 | 
					    ## create instance object
 | 
				
			||||||
    inst = bpy.data.objects.new(col.name, None)
 | 
					    inst = bpy.data.objects.new(col.name, None)
 | 
				
			||||||
 | 
				
			|||||||
@ -180,7 +180,7 @@ def get_asset_source(replace_local=False):
 | 
				
			|||||||
        source_path = re.sub(actionlib_dir_local, actionlib_dir, source_path)
 | 
					        source_path = re.sub(actionlib_dir_local, actionlib_dir, source_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return source_path
 | 
					    return source_path
 | 
				
			||||||
""""
 | 
					"""
 | 
				
			||||||
'''
 | 
					'''
 | 
				
			||||||
def get_catalog_path(filepath=None):
 | 
					def get_catalog_path(filepath=None):
 | 
				
			||||||
    filepath = filepath or bpy.data.filepath
 | 
					    filepath = filepath or bpy.data.filepath
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								common/preview.blend
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								common/preview.blend
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -9,6 +9,8 @@ if 'bpy' in locals():
 | 
				
			|||||||
    importlib.reload(gui)
 | 
					    importlib.reload(gui)
 | 
				
			||||||
    importlib.reload(keymaps)
 | 
					    importlib.reload(keymaps)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import bpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register():
 | 
					def register():
 | 
				
			||||||
    operators.register()
 | 
					    operators.register()
 | 
				
			||||||
    keymaps.register()
 | 
					    keymaps.register()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								file/gui.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								file/gui.py
									
									
									
									
									
								
							@ -14,13 +14,21 @@ from bpy.types import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from bpy_extras import asset_utils
 | 
					from bpy_extras import asset_utils
 | 
				
			||||||
from asset_library.common.bl_utils import get_object_libraries, get_addon_prefs
 | 
					from asset_library.common.bl_utils import get_object_libraries, get_addon_prefs
 | 
				
			||||||
 | 
					from asset_library.common.functions import get_active_library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def draw_context_menu(self, context):
 | 
					def draw_context_menu(layout):
 | 
				
			||||||
    layout = self.layout
 | 
					 | 
				
			||||||
    #asset = context.active_file
 | 
					    #asset = context.active_file
 | 
				
			||||||
 | 
					    layout.operator_context = "INVOKE_DEFAULT"
 | 
				
			||||||
 | 
					    lib = get_active_library()
 | 
				
			||||||
 | 
					    filepath = lib.adapter.get_active_asset_path()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    layout.operator("assetlib.open_blend_file", text="Open Blend File")#.filepath = asset.asset_data['filepath']
 | 
					    layout.operator("assetlib.open_blend_file", text="Open Blend File")#.filepath = asset.asset_data['filepath']
 | 
				
			||||||
 | 
					    op = layout.operator("wm.link", text="Link")
 | 
				
			||||||
 | 
					    op.filepath = str(filepath)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    op = layout.operator("wm.append", text="Append")
 | 
				
			||||||
 | 
					    op.filepath = str(filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def draw_header(layout):
 | 
					def draw_header(layout):
 | 
				
			||||||
 | 
				
			|||||||
@ -36,9 +36,9 @@ class ASSETLIB_OT_open_blend_file(Operator):
 | 
				
			|||||||
    def execute(self, context: Context) -> Set[str]:
 | 
					    def execute(self, context: Context) -> Set[str]:
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        lib = get_active_library()
 | 
					        lib = get_active_library()
 | 
				
			||||||
        print(lib, lib.data_type)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        filepath = context.active_file.asset_data['filepath']
 | 
					        filepath = lib.get_active_asset_path()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        open_blender_file(filepath)
 | 
					        open_blender_file(filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return {'FINISHED'}
 | 
					        return {'FINISHED'}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								file/preview.blend
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								file/preview.blend
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										21
									
								
								operators.py
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								operators.py
									
									
									
									
									
								
							@ -302,7 +302,7 @@ class ASSETLIB_OT_bundle_library(Operator):
 | 
				
			|||||||
    blocking : BoolProperty(default=False)
 | 
					    blocking : BoolProperty(default=False)
 | 
				
			||||||
    mode : EnumProperty(items=[(i.replace(' ', '_').upper(), i, '') for i in ('None', 'All', 'Auto Bundle')], default='NONE')
 | 
					    mode : EnumProperty(items=[(i.replace(' ', '_').upper(), i, '') for i in ('None', 'All', 'Auto Bundle')], default='NONE')
 | 
				
			||||||
    directory : StringProperty(subtype='DIR_PATH')
 | 
					    directory : StringProperty(subtype='DIR_PATH')
 | 
				
			||||||
    conform : BoolProperty(default=False)
 | 
					    #conform : BoolProperty(default=False)
 | 
				
			||||||
    #def refresh(self):
 | 
					    #def refresh(self):
 | 
				
			||||||
    #    for area in suitable_areas(bpy.context.screen):
 | 
					    #    for area in suitable_areas(bpy.context.screen):
 | 
				
			||||||
    #        bpy.ops.asset.library_refresh({"area": area, 'region': area.regions[3]})
 | 
					    #        bpy.ops.asset.library_refresh({"area": area, 'region': area.regions[3]})
 | 
				
			||||||
@ -327,10 +327,6 @@ class ASSETLIB_OT_bundle_library(Operator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        print(f'Bundle Libraries: {[l.name for l in libs]}')
 | 
					        print(f'Bundle Libraries: {[l.name for l in libs]}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        adapter = "lib.adapter"
 | 
					 | 
				
			||||||
        if self.conform:
 | 
					 | 
				
			||||||
            adapter = "lib.conform.adapter"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        script_code = dedent(f"""
 | 
					        script_code = dedent(f"""
 | 
				
			||||||
            import bpy
 | 
					            import bpy
 | 
				
			||||||
            prefs = bpy.context.preferences.addons["asset_library"].preferences
 | 
					            prefs = bpy.context.preferences.addons["asset_library"].preferences
 | 
				
			||||||
@ -338,7 +334,7 @@ class ASSETLIB_OT_bundle_library(Operator):
 | 
				
			|||||||
            for lib_data in {lib_datas}:
 | 
					            for lib_data in {lib_datas}:
 | 
				
			||||||
                lib = prefs.env_libraries.add()
 | 
					                lib = prefs.env_libraries.add()
 | 
				
			||||||
                lib.set_dict(lib_data)
 | 
					                lib.set_dict(lib_data)
 | 
				
			||||||
                {adapter}.bundle(cache_diff='{self.diff}')
 | 
					                lib.adapter.bundle(cache_diff='{self.diff}')
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            bpy.ops.wm.quit_blender()
 | 
					            bpy.ops.wm.quit_blender()
 | 
				
			||||||
            """)
 | 
					            """)
 | 
				
			||||||
@ -400,7 +396,7 @@ class ASSETLIB_OT_diff(Operator):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return {'FINISHED'}
 | 
					        return {'FINISHED'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
class ASSETLIB_OT_conform_library(Operator):
 | 
					class ASSETLIB_OT_conform_library(Operator):
 | 
				
			||||||
    bl_idname = "assetlib.conform_library"
 | 
					    bl_idname = "assetlib.conform_library"
 | 
				
			||||||
    bl_options = {"REGISTER", "UNDO"}
 | 
					    bl_options = {"REGISTER", "UNDO"}
 | 
				
			||||||
@ -445,7 +441,7 @@ class ASSETLIB_OT_conform_library(Operator):
 | 
				
			|||||||
    def invoke(self, context, event):
 | 
					    def invoke(self, context, event):
 | 
				
			||||||
        context.window_manager.fileselect_add(self)
 | 
					        context.window_manager.fileselect_add(self)
 | 
				
			||||||
        return {'RUNNING_MODAL'}
 | 
					        return {'RUNNING_MODAL'}
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ASSETLIB_OT_generate_previews(Operator):
 | 
					class ASSETLIB_OT_generate_previews(Operator):
 | 
				
			||||||
    bl_idname = "assetlib.generate_previews"
 | 
					    bl_idname = "assetlib.generate_previews"
 | 
				
			||||||
@ -453,7 +449,7 @@ class ASSETLIB_OT_generate_previews(Operator):
 | 
				
			|||||||
    bl_label = "Generate Previews"
 | 
					    bl_label = "Generate Previews"
 | 
				
			||||||
    bl_description = "Generate and write the image for assets"
 | 
					    bl_description = "Generate and write the image for assets"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    diff : StringProperty()
 | 
					    cache : StringProperty()
 | 
				
			||||||
    preview_blend : StringProperty()
 | 
					    preview_blend : StringProperty()
 | 
				
			||||||
    name : StringProperty()
 | 
					    name : StringProperty()
 | 
				
			||||||
    blocking : BoolProperty(default=True)
 | 
					    blocking : BoolProperty(default=True)
 | 
				
			||||||
@ -476,6 +472,9 @@ class ASSETLIB_OT_generate_previews(Operator):
 | 
				
			|||||||
        # subprocess.call(cmd)
 | 
					        # subprocess.call(cmd)
 | 
				
			||||||
        preview_blend = self.preview_blend or lib.adapter.preview_blend
 | 
					        preview_blend = self.preview_blend or lib.adapter.preview_blend
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        if not preview_blend or not Path(preview_blend).exists():
 | 
				
			||||||
 | 
					            preview_blend = MODULE_DIR / 'common' / 'preview.blend'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        script_path = Path(bpy.app.tempdir) / 'generate_previews.py'
 | 
					        script_path = Path(bpy.app.tempdir) / 'generate_previews.py'
 | 
				
			||||||
        script_code = dedent(f"""
 | 
					        script_code = dedent(f"""
 | 
				
			||||||
            import bpy
 | 
					            import bpy
 | 
				
			||||||
@ -484,7 +483,7 @@ class ASSETLIB_OT_generate_previews(Operator):
 | 
				
			|||||||
            lib.set_dict({lib.to_dict()})
 | 
					            lib.set_dict({lib.to_dict()})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bpy.ops.wm.open_mainfile(filepath='{preview_blend}', load_ui=True)
 | 
					            bpy.ops.wm.open_mainfile(filepath='{preview_blend}', load_ui=True)
 | 
				
			||||||
            lib.conform.adapter.generate_previews()
 | 
					            lib.adapter.generate_previews(cache='{self.cache}')
 | 
				
			||||||
            """)
 | 
					            """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        script_path.write_text(script_code)
 | 
					        script_path.write_text(script_code)
 | 
				
			||||||
@ -609,7 +608,7 @@ classes = (
 | 
				
			|||||||
    ASSETLIB_OT_bundle_library,
 | 
					    ASSETLIB_OT_bundle_library,
 | 
				
			||||||
    ASSETLIB_OT_clear_asset,
 | 
					    ASSETLIB_OT_clear_asset,
 | 
				
			||||||
    ASSETLIB_OT_edit_data,
 | 
					    ASSETLIB_OT_edit_data,
 | 
				
			||||||
    ASSETLIB_OT_conform_library,
 | 
					    #ASSETLIB_OT_conform_library,
 | 
				
			||||||
    ASSETLIB_OT_reload_addon
 | 
					    ASSETLIB_OT_reload_addon
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										87
									
								
								prefs.py
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								prefs.py
									
									
									
									
									
								
							@ -83,7 +83,7 @@ class AssetLibraryAdapters(PropertyGroup):
 | 
				
			|||||||
    def __iter__(self):
 | 
					    def __iter__(self):
 | 
				
			||||||
        return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name'))
 | 
					        return (getattr(self, p) for p in self.bl_rna.properties.keys() if p not in ('rna_type', 'name'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
class ConformAssetLibrary(PropertyGroup):
 | 
					class ConformAssetLibrary(PropertyGroup):
 | 
				
			||||||
    adapters : bpy.props.PointerProperty(type=AssetLibraryAdapters)
 | 
					    adapters : bpy.props.PointerProperty(type=AssetLibraryAdapters)
 | 
				
			||||||
    adapter_name : EnumProperty(items=get_adapter_items)
 | 
					    adapter_name : EnumProperty(items=get_adapter_items)
 | 
				
			||||||
@ -117,16 +117,19 @@ class ConformAssetLibrary(PropertyGroup):
 | 
				
			|||||||
        del data['adapters']
 | 
					        del data['adapters']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AssetLibrary(PropertyGroup):
 | 
					class AssetLibrary(PropertyGroup):
 | 
				
			||||||
    name : StringProperty(name='Name', default='Action Library', update=update_library_path)
 | 
					    name : StringProperty(name='Name', default='Action Library', update=update_library_path)
 | 
				
			||||||
    id : StringProperty()
 | 
					    id : StringProperty()
 | 
				
			||||||
    auto_bundle : BoolProperty(name='Auto Bundle', default=True)
 | 
					    auto_bundle : BoolProperty(name='Auto Bundle', default=False)
 | 
				
			||||||
    expand : BoolProperty(name='Expand', default=False)
 | 
					    expand : BoolProperty(name='Expand', default=False)
 | 
				
			||||||
    use : BoolProperty(name='Use', default=True, update=update_library_path)
 | 
					    use : BoolProperty(name='Use', default=True, update=update_library_path)
 | 
				
			||||||
    data_type : EnumProperty(name='Type', items=DATA_TYPE_ITEMS, default='COLLECTION')
 | 
					    data_type : EnumProperty(name='Type', items=DATA_TYPE_ITEMS, default='COLLECTION')
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    template_image : StringProperty(default='', description='../{name}_image.png')
 | 
				
			||||||
 | 
					    template_video : StringProperty(default='', description='../{name}_video.mov')
 | 
				
			||||||
 | 
					    template_description : StringProperty(default='', description='../{name}_asset_description.json')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bundle_directory : StringProperty(
 | 
					    bundle_directory : StringProperty(
 | 
				
			||||||
        name="Bundle Directory",
 | 
					        name="Bundle Directory",
 | 
				
			||||||
@ -153,7 +156,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    template: StringProperty()
 | 
					    template: StringProperty()
 | 
				
			||||||
    expand_extra : BoolProperty(name='Expand', default=False)
 | 
					    expand_extra : BoolProperty(name='Expand', default=False)
 | 
				
			||||||
    blend_depth : IntProperty(name='Blend Depth', default=0)
 | 
					    blend_depth : IntProperty(name='Blend Depth', default=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # source_directory : StringProperty(
 | 
					    # source_directory : StringProperty(
 | 
				
			||||||
    #     name="Path",
 | 
					    #     name="Path",
 | 
				
			||||||
@ -166,8 +169,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
    #adapter : EnumProperty(items=adapter_ITEMS)
 | 
					    #adapter : EnumProperty(items=adapter_ITEMS)
 | 
				
			||||||
    adapters : bpy.props.PointerProperty(type=AssetLibraryAdapters)
 | 
					    adapters : bpy.props.PointerProperty(type=AssetLibraryAdapters)
 | 
				
			||||||
    adapter_name : EnumProperty(items=get_adapter_items)
 | 
					    adapter_name : EnumProperty(items=get_adapter_items)
 | 
				
			||||||
 | 
					    parent : StringProperty()
 | 
				
			||||||
    conform: bpy.props.PointerProperty(type=ConformAssetLibrary)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # data_file_path : StringProperty(
 | 
					    # data_file_path : StringProperty(
 | 
				
			||||||
    #     name="Path",
 | 
					    #     name="Path",
 | 
				
			||||||
@ -175,8 +177,6 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
    #     default='',
 | 
					    #     default='',
 | 
				
			||||||
    # )
 | 
					    # )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #expand_conform : BoolProperty(name='Expand Conform', default=False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #def __init__(self):
 | 
					    #def __init__(self):
 | 
				
			||||||
    #    self.adapters.parent = self
 | 
					    #    self.adapters.parent = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -185,9 +185,17 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
       prefs = get_addon_prefs()
 | 
					       prefs = get_addon_prefs()
 | 
				
			||||||
       return [l for l in prefs.libraries if l != self and (l.library_path == self.library_path)]
 | 
					       return [l for l in prefs.libraries if l != self and (l.library_path == self.library_path)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def child_libraries(self):
 | 
				
			||||||
 | 
					       prefs = get_addon_prefs()
 | 
				
			||||||
 | 
					       return [l for l in prefs.libraries if l != self and (l.parent == self.name)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def data_types(self):
 | 
					    def data_types(self):
 | 
				
			||||||
        return f'{self.data_type.lower()}s'
 | 
					        data_type = self.data_type
 | 
				
			||||||
 | 
					        if data_type == 'FILE':
 | 
				
			||||||
 | 
					            data_type = 'COLLECTION'
 | 
				
			||||||
 | 
					        return f'{data_type.lower()}s'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def adapter(self):
 | 
					    def adapter(self):
 | 
				
			||||||
@ -217,7 +225,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
        #    library_name = norm_str(library_name)
 | 
					        #    library_name = norm_str(library_name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.use_custom_bundle_directory:
 | 
					        if self.use_custom_bundle_directory:
 | 
				
			||||||
            return Path(self.custom_bundle_directory, library_name).resolve()
 | 
					            return Path(self.custom_bundle_directory).resolve()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            library_name = norm_str(library_name)
 | 
					            library_name = norm_str(library_name)
 | 
				
			||||||
            return Path(prefs.bundle_directory, library_name).resolve()
 | 
					            return Path(prefs.bundle_directory, library_name).resolve()
 | 
				
			||||||
@ -229,29 +237,6 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        return self.name
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_image(self):
 | 
					 | 
				
			||||||
        prefs = get_addon_prefs()
 | 
					 | 
				
			||||||
        return prefs.template_image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_video(self):
 | 
					 | 
				
			||||||
        prefs = get_addon_prefs()
 | 
					 | 
				
			||||||
        return prefs.template_video
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def template_description(self):
 | 
					 | 
				
			||||||
        prefs = get_addon_prefs()
 | 
					 | 
				
			||||||
        return prefs.template_description
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #@property
 | 
					 | 
				
			||||||
    #def catalog_path(self):
 | 
					 | 
				
			||||||
    #    return get_catalog_path(self.library_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def options(self):
 | 
					 | 
				
			||||||
        return {k: getattr(self.adapter, k) for k, v in self.options.bl_rna.properties.keys() if p !='rna_type'}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def clear_library_path(self):
 | 
					    def clear_library_path(self):
 | 
				
			||||||
        #print('Clear Library Path', self.name)
 | 
					        #print('Clear Library Path', self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -348,7 +333,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
        data['adapter']['name'] = data.pop('adapter_name')
 | 
					        data['adapter']['name'] = data.pop('adapter_name')
 | 
				
			||||||
        del data['adapters']
 | 
					        del data['adapters']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data['conform'] = self.conform.to_dict()
 | 
					        #data['conform'] = self.conform.to_dict()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -448,6 +433,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        layout.separator(factor=3)
 | 
					        layout.separator(factor=3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
    def draw_extra(self, layout):
 | 
					    def draw_extra(self, layout):
 | 
				
			||||||
        #box = layout.box()
 | 
					        #box = layout.box()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -503,15 +489,14 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
                      
 | 
					                      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        col.separator()
 | 
					        col.separator()
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw(self, layout):
 | 
					    def draw(self, layout):
 | 
				
			||||||
        prefs = get_addon_prefs()
 | 
					        prefs = get_addon_prefs()
 | 
				
			||||||
 | 
					        #box = layout.box()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        box = layout.box()
 | 
					        row = layout.row(align=True)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        row = box.row(align=True)
 | 
					 | 
				
			||||||
        #row.use_property_split = False
 | 
					        #row.use_property_split = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #row.alignment = 'LEFT'
 | 
					        #row.alignment = 'LEFT'
 | 
				
			||||||
@ -544,7 +529,7 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
            sub_row.label(icon='FAKE_USER_ON')
 | 
					            sub_row.label(icon='FAKE_USER_ON')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.expand:
 | 
					        if self.expand:
 | 
				
			||||||
            col = box.column(align=False)
 | 
					            col = layout.column(align=False)
 | 
				
			||||||
            col.use_property_split = True
 | 
					            col.use_property_split = True
 | 
				
			||||||
            #row = col.row(align=True)
 | 
					            #row = col.row(align=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -564,12 +549,22 @@ class AssetLibrary(PropertyGroup):
 | 
				
			|||||||
                label='Custom Bundle Directory',
 | 
					                label='Custom Bundle Directory',
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            col.prop(self, "blend_depth")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            subcol = col.column(align=True)
 | 
				
			||||||
 | 
					            subcol.prop(self, "template_description", text='Template Description', icon='COPY_ID')
 | 
				
			||||||
 | 
					            subcol.prop(self, "template_image", text='Template Image', icon='COPY_ID')
 | 
				
			||||||
 | 
					            subcol.prop(self, "template_video", text='Template Video', icon='COPY_ID')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if self.adapter:
 | 
					            if self.adapter:
 | 
				
			||||||
                col.separator()
 | 
					                col.separator()
 | 
				
			||||||
                self.adapter.draw_prefs(col)
 | 
					                self.adapter.draw_prefs(col)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					            for lib in self.child_libraries:
 | 
				
			||||||
 | 
					                lib.draw(layout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            col.separator()
 | 
					            col.separator()
 | 
				
			||||||
            self.draw_extra(col)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -662,10 +657,7 @@ class AssetLibraryPrefs(AddonPreferences):
 | 
				
			|||||||
        update=update_all_library_path
 | 
					        update=update_all_library_path
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #use_single_path : BoolProperty(default=True)
 | 
					
 | 
				
			||||||
    #template_description : StringProperty(default='../{name}_asset_description.json')
 | 
					 | 
				
			||||||
    #template_image : StringProperty(default='../{name}_image.png')
 | 
					 | 
				
			||||||
    #template_video : StringProperty(default='../{name}_video.mov')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config_directory : StringProperty(
 | 
					    config_directory : StringProperty(
 | 
				
			||||||
        name="Config Path",
 | 
					        name="Config Path",
 | 
				
			||||||
@ -773,8 +765,11 @@ class AssetLibraryPrefs(AddonPreferences):
 | 
				
			|||||||
            col.operator("assetlib.add_user_library", text='Bundle All Libraries', icon='MOD_BUILD')
 | 
					            col.operator("assetlib.add_user_library", text='Bundle All Libraries', icon='MOD_BUILD')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for lib in self.libraries:# list(self.env_libraries) + list(self.user_libraries):
 | 
					        for lib in self.libraries:# list(self.env_libraries) + list(self.user_libraries):
 | 
				
			||||||
 | 
					            if lib.parent:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            lib.draw(main_col)
 | 
					            box = main_col.box()
 | 
				
			||||||
 | 
					            lib.draw(box)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        row = main_col.row()
 | 
					        row = main_col.row()
 | 
				
			||||||
        row.alignment = 'RIGHT'
 | 
					        row.alignment = 'RIGHT'
 | 
				
			||||||
@ -783,7 +778,7 @@ class AssetLibraryPrefs(AddonPreferences):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
classes = [
 | 
					classes = [
 | 
				
			||||||
    AssetLibraryAdapters,
 | 
					    AssetLibraryAdapters,
 | 
				
			||||||
    ConformAssetLibrary,
 | 
					    #ConformAssetLibrary,
 | 
				
			||||||
    AssetLibrary,
 | 
					    AssetLibrary,
 | 
				
			||||||
    AssetLibraryPrefs,
 | 
					    AssetLibraryPrefs,
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user