From 7a43cfaf2f2ef43b9a440c9f8c67974685e0cd1f Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sat, 31 May 2025 16:31:50 +0200 Subject: [PATCH] [feature] unload glyphs and refresh fonts --- __init__.py | 85 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/__init__.py b/__init__.py index 6e071a0..19043fb 100644 --- a/__init__.py +++ b/__init__.py @@ -383,7 +383,10 @@ class ABC3D_PT_FontList(bpy.types.Panel): abc3d_data, "active_font_index", ) - if abc3d_data.active_font_index >= 0: + if ( + abc3d_data.active_font_index >= 0 + and len(abc3d_data.available_fonts) > abc3d_data.active_font_index + ): available_font = abc3d_data.available_fonts[abc3d_data.active_font_index] font_name = available_font.font_name face_name = available_font.face_name @@ -432,6 +435,15 @@ class ABC3D_PT_FontList(bpy.types.Panel): ) oper_lf.font_name = font_name oper_lf.face_name = face_name + box = layout.box() + row = box.row() + row.label(text="File and Memory optimization") + row = box.row() + row.operator(f"{__name__}.refresh_fonts", text="Refresh Font list from disk") + row = box.row() + row.operator( + f"{__name__}.unload_unused_glyphs", text="Unload unused glyphs from memory" + ) class ABC3D_PT_TextPlacement(bpy.types.Panel): @@ -773,33 +785,6 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel): return g return None - # def font_items_callback(self, context): - # items = [] - # fonts = Font.get_loaded_fonts_and_faces() - # for f in fonts: - # items.append((f"{f[0]} {f[1]}", f"{f[0]} {f[1]}", "")) - # return items - - # def font_default_callback(self, context): - # t = self.get_active_text_properties(self) - # if type(t) != type(None): - # return f"{t.font_name} {t.face_name}" - # else: - # return None - - # def font_update_callback(self, context): - # font_name, face_name = self.font.split(" ") - # t = self.get_active_text_properties(self) - # t.font_name = font_name - # t.face_name = face_name - # butils.set_text_on_curve(t) - - # font: bpy.props.EnumProperty( - # items=font_items_callback, - # default=font_default_callback, - # update=font_update_callback, - # ) - @classmethod def poll(self, context): try: @@ -843,6 +828,33 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel): box.row().prop(glyph_props, "letter_spacing") +class ABC3D_OT_RefreshAvailableFonts(bpy.types.Operator): + """Refreshes available font list from disk. + This also removes all fonts which are not saved in the asset directory. + Can be useful when creating fonts or manually installing fonts.""" + + bl_idname = f"{__name__}.refresh_fonts" + bl_label = "Refresh Available Fonts" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + refresh_fonts() + return {"FINISHED"} + + +class ABC3D_OT_UnloadUnusedGlyphs(bpy.types.Operator): + """Unload all glyphs which are not actively used in this project from memory. + They will still be normally loaded when you use them again.""" + + bl_idname = f"{__name__}.unload_unused_glyphs" + bl_label = "Unload Unused Glyphs" + bl_options = {"REGISTER", "UNDO"} + + def execute(self, context): + butils.unload_unused_glyphs() + return {"FINISHED"} + + class ABC3D_OT_InstallFont(bpy.types.Operator): """Install or load Fontfile from path above. (Format must be *.glb or *.gltf)""" @@ -1851,6 +1863,8 @@ classes = ( ABC3D_PT_NamingHelper, ABC3D_PT_TextPropertiesPanel, ABC3D_OT_OpenAssetDirectory, + ABC3D_OT_RefreshAvailableFonts, + ABC3D_OT_UnloadUnusedGlyphs, ABC3D_OT_LoadInstalledFonts, ABC3D_OT_LoadFont, ABC3D_OT_AddDefaultMetrics, @@ -1954,6 +1968,21 @@ def load_used_glyphs(): butils.load_font_from_filepath(fp, a.unloaded) +def refresh_fonts(): + fontcollection: bpy_types.Collection = bpy.data.collections.get("ABC3D") + if fontcollection is not None: + objs = [o for o in fontcollection.objects if o.parent == None] + butils.completely_delete_objects(objs) + butils.run_in_main_thread(Font.fonts.clear) + butils.run_in_main_thread(butils.clear_available_fonts) + butils.run_in_main_thread(butils.register_installed_fonts) + butils.run_in_main_thread(butils.update_available_fonts) + butils.run_in_main_thread(load_used_glyphs) + butils.run_in_main_thread(butils.update_types) + butils.run_in_main_thread(detect_text) + butils.run_in_main_thread(butils.unload_unused_glyphs) + + @persistent def load_handler(self, dummy): if not bpy.app.timers.is_registered(butils.execute_queued_functions):