[feature] unload glyphs and refresh fonts

This commit is contained in:
jrkb 2025-05-31 16:31:50 +02:00
parent 2dcd4e7a2c
commit 7a43cfaf2f

View file

@ -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):