def get_scs_banner_img_data(window): """Loads image to blender data block, loads it to gl memory and gets bindcode address that can be used in bgl module for image drawing. :param window: window for which we should get banner image :type window: bpy.type.Window :return: (bindcode of scs banner image, width of scs banner image, height of scs banner image :rtype: (int, int, int) """ if SCS_TOOLS_OT_Show3DViewReport.has_controls(window): img_name = _OP_consts.View3DReport.BT_BANNER_WITH_CTRLS_IMG_NAME else: img_name = _OP_consts.View3DReport.BT_BANNER_IMG_NAME if img_name not in bpy.data.images: img_path = os.path.join( _path_utils.get_addon_installation_paths()[0], "ui", "banners", img_name) img = bpy.data.images.load(img_path, check_existing=True) img.colorspace_settings.name = 'Raw' else: img = bpy.data.images[img_name] # ensure that image is loaded in GPU memory aka has proper bindcode, # we have to that each time because if operator is shown for long time blender might free it on it's own if img.bindcode == 0: img.gl_load() return img.bindcode, img.size[0], img.size[1]
def init(): """Initialization function for getting hold of preview collection variable with already created custom icon objects. """ if CUSTOM_ICONS not in _preview_collections: pcoll = previews.new() # load icons tools_paths = _path.get_addon_installation_paths() if len(tools_paths) > 0: for icon_type in _ICON_consts.Types.as_list(): # create path to current icon "ui/icons/icon_type" icon_path = os.path.join( tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type) if os.path.isfile(icon_path): if icon_type not in pcoll: pcoll.load(icon_type, icon_path, 'IMAGE') else: lprint( "W Icon %r is missing. Please try to install addon again!", (icon_type, )) _preview_collections[CUSTOM_ICONS] = pcoll
def _load_image(icon_type): """Loads image for given icon type if path exists. :param icon_type: one of icons type from "io_scs_tools.consts.Icons.Types" :type icon_type: str :return: True if image is succesfully loaded; False otherwise :rtype: bool """ tools_paths = _path.get_addon_installation_paths() if len(tools_paths) > 0: # create path to current icon "ui/icons/icon_type" icon_path = os.path.join(tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type) if os.path.isfile(icon_path): if not icon_type in bpy.data.images: bpy.data.images.load(icon_path) return True else: lprint("W Icon %r is missing. Please try to install addon again!", (icon_type,)) return False
def get_config_filepath(): """Returns a valid filepath to "config.txt" file. If the file doesn't exists it creates empty one.""" scs_installation_dirs = _path.get_addon_installation_paths() # SEARCH FOR CONFIG... scs_config_file = '' for i, location in enumerate(scs_installation_dirs): test_path = os.path.join(location, 'config.txt') if os.path.isfile(test_path): scs_config_file = test_path break # IF NO CONFIG FILE, CREATE ONE... if scs_config_file == '': scs_config_file = new_config_file(os.path.join(scs_installation_dirs[0], 'config.txt')) # print('\tMaking "config.txt" file:\n\t "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt')) # print('SCS Blender Tools Config File:\n "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt')) return scs_config_file
def get_config_filepath(): """Returns a valid filepath to "config.txt" file. If the file doesn't exists it creates empty one.""" scs_installation_dirs = _path_utils.get_addon_installation_paths() # SEARCH FOR CONFIG... scs_config_file = '' for i, location in enumerate(scs_installation_dirs): test_path = os.path.join(location, 'config.txt') if os.path.isfile(test_path): scs_config_file = test_path break # IF NO CONFIG FILE, CREATE ONE... if scs_config_file == '': scs_config_file = new_config_file(os.path.join(scs_installation_dirs[0], 'config.txt')) # print('\tMaking "config.txt" file:\n\t "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt')) # print('SCS Blender Tools Config File:\n "%s"\n' % os.path.join(scs_installation_dirs[0], 'config.txt')) return scs_config_file
def _load_image(icon_type): """Loads image for given icon type if path exists. :param icon_type: one of icons type from "io_scs_tools.consts.Icons.Types" :type icon_type: str :return: True if image is succesfully loaded; False otherwise :rtype: bool """ tools_paths = _path.get_addon_installation_paths() if len(tools_paths) > 0: # create path to current icon "ui/icons/icon_type" icon_path = os.path.join(tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type) if os.path.isfile(icon_path): if not icon_type in bpy.data.images: bpy.data.images.load(icon_path) return True else: lprint("W Icon %r is missing. Please try to install addon again!", (icon_type, )) return False
def init(): """Initialization function for getting hold of preview collection variable with already created custom icon objects. """ # create new preview only once. # NOTE: We removed previews cleanup from code # because it was crashing Blender when rapidly enabling/disabling BT addon. # So instead of always creating new preview collection we rather reuse existing and # only load icons again with force reload flag, to ensure icons are always reloaded when init is called. if CUSTOM_ICONS not in _preview_collections: pcoll = previews.new() _preview_collections[CUSTOM_ICONS] = pcoll else: pcoll = _preview_collections[CUSTOM_ICONS] print( "INFO\t - Icon collection is already in python memory, re-using it!" ) # load icons tools_paths = _path.get_addon_installation_paths() if len(tools_paths) > 0: for icon_type in _ICON_consts.Types.as_list(): # create path to current icon "ui/icons/icon_type" icon_path = os.path.join( tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type) if os.path.isfile(icon_path): if icon_type not in pcoll: pcoll.load(icon_type, icon_path, 'IMAGE', force_reload=True) else: lprint( "W Icon %r is missing. Please try to install addon again!", (icon_type, ))
def init(): """Initialization function for getting hold of preview collection variable with already created custom icon objects. """ if CUSTOM_ICONS not in _preview_collections: pcoll = previews.new() # load icons tools_paths = _path.get_addon_installation_paths() if len(tools_paths) > 0: for icon_type in _ICON_consts.Types.as_list(): # create path to current icon "ui/icons/icon_type" icon_path = os.path.join(tools_paths[0], 'ui' + os.sep + 'icons' + os.sep + icon_type) if os.path.isfile(icon_path): if icon_type not in pcoll: pcoll.load(icon_type, icon_path, 'IMAGE') else: lprint("W Icon %r is missing. Please try to install addon again!", (icon_type,)) _preview_collections[CUSTOM_ICONS] = pcoll
def get_scs_logo_img_bindcode(): """Loads image to blender data block, loads it to gl memory and gets bindcode address that can be used in bgl module for image drawing. :return: bindcode of scs bt logo image :rtype: int """ if _OP_consts.View3DReport.BT_LOGO_IMG_NAME not in bpy.data.images: img_path = _path_utils.get_addon_installation_paths()[0] + "/ui/icons/" + _OP_consts.View3DReport.BT_LOGO_IMG_NAME img = bpy.data.images.load(img_path, check_existing=True) else: img = bpy.data.images[_OP_consts.View3DReport.BT_LOGO_IMG_NAME] # ensure that image is loaded in GPU memory aka has proper bindcode, # we have to that each time because if operator is shown for long time blender might free it on his own if img.bindcode[0] == 0: img.gl_load(0, GL_NEAREST, GL_NEAREST) return img.bindcode[0]
def register(): """Initialization function for getting hold of preview collection variable with already created custom icon objects. """ tools_paths = _path.get_addon_installation_paths() if len(tools_paths) <= 0: return # load icon themes icon_themes_dir = os.path.join(tools_paths[0], 'ui', 'icons') if not os.path.isdir(icon_themes_dir): return theme_idx = 0 for theme_name in os.listdir(icon_themes_dir): icon_theme_dir = os.path.join(icon_themes_dir, theme_name) # ignore all none directory entries if not os.path.isdir(icon_theme_dir): continue # create new preview only once. # NOTE: We removed previews cleanup from code # because it was crashing Blender when rapidly enabling/disabling BT addon. # So instead of always creating new preview collection we rather reuse existing and # only load icons again with force reload flag, to ensure icons are always reloaded when init is called. if theme_name not in _cache[PCOLLS]: pcoll = previews.new() _cache[PCOLLS][theme_name] = pcoll _cache[PCOLLS_NAME_MAP][theme_idx] = theme_name _cache[PCOLLS_IDX_MAP][theme_name] = theme_idx theme_idx += 1 else: pcoll = _cache[PCOLLS][theme_name] print( "INFO\t- Icon collection is already in python memory, re-using it!" ) for icon_type in _ICON_consts.Types.as_list(): # create path to current icon "ui/icons/<theme_name>/<icon_type>" icon_path = os.path.join(icon_theme_dir, icon_type) if os.path.isfile(icon_path): if icon_type not in pcoll: pcoll.load(icon_type, icon_path, 'IMAGE', force_reload=True) else: print( "WARNING\t- Icon %r is missing. Please try to install addon again!" % icon_type) # if current theme doesn't exists, use first instead if _cache[CURRENT_THEME] not in _cache[PCOLLS] and len(_cache[PCOLLS]) > 0: set_theme(get_theme_name(0)) print( "WARNING\t- Default icon theme doesn't exist, fallback to first available!" )
def execute(self, context): # find group names created by Blender Tools with # dynamic importing of all modules from "internals/shaders" folder # and checking if module has "get_node_group" functions which indicates that # module creates node group groups_to_remove = [ "AddEnvGroup", # from v0.6 "FresnelGroup", # from v0.6 "LampmaskMixerGroup", # from v0.6 "ReflectionNormalGroup", # from v0.6 ] for root, dirs, files in os.walk( _path_utils.get_addon_installation_paths()[0] + os.sep + "internals/shaders"): for file in files: if not file.endswith(".py"): continue module = SourceFileLoader(root + os.sep + file, root + os.sep + file).load_module() if "get_node_group" in dir(module): ng = module.get_node_group() groups_to_remove.append(ng.name) # 1. clear nodes on materials for mat in bpy.data.materials: if not mat.node_tree: continue # also check none blender tools materials just to remove possible nodes usage of our groups if mat.scs_props.active_shader_preset_name == "<none>": nodes_to_remove = [] # check for possible leftover usage of our node groups for node in mat.node_tree.nodes: # filter out nodes which are not node group and node groups without node tree if node.type != "GROUP" or not node.node_tree: continue if node.node_tree.name in groups_to_remove: nodes_to_remove.append(node.node_tree.name) # remove possible leftover used node group nodes for node_name in nodes_to_remove: mat.node_tree.nodes.remove( mat.node_tree.nodes[node_name]) continue mat.node_tree.nodes.clear() # 2. clear nodes on node groups for ng_name in groups_to_remove: if ng_name not in bpy.data.node_groups: continue ng = bpy.data.node_groups[ng_name] ng.nodes.clear() # 3. remove node groups from blender data blocks for ng_name in groups_to_remove: if ng_name not in bpy.data.node_groups: continue bpy.data.node_groups.remove(bpy.data.node_groups[ng_name], do_unlink=True) # 4. finally set preset to material again, which will update nodes and possible input interface changes scs_roots = _object_utils.gather_scs_roots(bpy.data.objects) for mat in bpy.data.materials: # ignore none blender tools materials if mat.scs_props.active_shader_preset_name == "<none>": continue material_textures = {} if "scs_shader_attributes" in mat and "textures" in mat[ "scs_shader_attributes"]: for texture in mat["scs_shader_attributes"][ "textures"].values(): tex_id = texture["Tag"].split(":")[1] tex_value = texture["Value"] material_textures[tex_id] = tex_value (preset_name, preset_section) = _material_utils.find_preset( mat.scs_props.mat_effect_name, material_textures) if preset_section: _material_utils.set_shader_data_to_material( mat, preset_section) # sync shader types on all scs roots by updating looks on them # without this call we might end up with outdated looks raising errors once user will switch to them for scs_root in scs_roots: _looks.update_look_from_material(scs_root, mat, True) return {'FINISHED'}
def execute(self, context): # find group names created by Blender Tools with # dynamic importing of all modules from "internals/shaders" folder # and checking if module has "get_node_group" functions which indicates that # module creates node group groups_to_remove = [ "AddEnvGroup", # from v0.6 "FresnelGroup", # from v0.6 "LampmaskMixerGroup", # from v0.6 "ReflectionNormalGroup", # from v0.6 ] for root, dirs, files in os.walk(_path_utils.get_addon_installation_paths()[0] + os.sep + "internals/shaders"): for file in files: if not file.endswith(".py"): continue module = SourceFileLoader(root + os.sep + file, root + os.sep + file).load_module() if "get_node_group" in dir(module): ng = module.get_node_group() groups_to_remove.append(ng.name) # 1. clear nodes on materials for mat in bpy.data.materials: if not mat.node_tree: continue if mat.scs_props.active_shader_preset_name == "<none>": nodes_to_remove = [] # check for possible leftover usage of our node groups for node in mat.node_tree.nodes: # filter out nodes which are not node group and node groups without node tree if node.type != "GROUP" or not node.node_tree: continue if node.node_tree.name in groups_to_remove: nodes_to_remove.append(node.node_tree.name) # remove possible leftover used node group nodes for node_name in nodes_to_remove: mat.node_tree.nodes.remove(mat.node_tree.nodes[node_name]) continue mat.node_tree.nodes.clear() # 2. clear nodes on node groups for ng_name in groups_to_remove: if ng_name not in bpy.data.node_groups: continue ng = bpy.data.node_groups[ng_name] ng.nodes.clear() # 3. remove node groups from blender data blocks for ng_name in groups_to_remove: if ng_name not in bpy.data.node_groups: continue bpy.data.node_groups.remove(bpy.data.node_groups[ng_name]) # 4. finally set preset to material again, which will update nodes and possible input interface changes for mat in bpy.data.materials: if mat.scs_props.active_shader_preset_name == "<none>": continue material_textures = {} if "scs_shader_attributes" in mat and "textures" in mat["scs_shader_attributes"]: for texture in mat["scs_shader_attributes"]["textures"].values(): tex_id = texture["Tag"].split(":")[1] tex_value = texture["Value"] material_textures[tex_id] = tex_value (preset_name, preset_section) = _material_utils.find_preset(mat.scs_props.mat_effect_name, material_textures) if preset_section: _material_utils.set_shader_data_to_material(mat, preset_section) return {'FINISHED'}