only import on demand

This commit is contained in:
jrkb 2024-08-21 14:42:53 +02:00
parent e23369df94
commit 25ef83878a
4 changed files with 722 additions and 107 deletions

View file

@ -25,10 +25,12 @@ if "bpy" in locals():
importlib.reload(Font)
importlib.reload(utils)
importlib.reload(butils)
importlib.reload(bimport)
else:
from .common import Font
from .common import utils
from . import butils
from . import bimport
import bpy
import math
@ -173,25 +175,35 @@ class ABC3D_text_properties(bpy.types.PropertyGroup):
else:
return 0 #""
def glyphs_update_callback(self, context):
butils.prepare_text(self.font_name,
self.face_name,
self.text)
butils.set_text_on_curve(self)
def update_callback(self, context):
butils.set_text_on_curve(self)
def font_update_callback(self, context):
font_name, face_name = self.font.split(" ")
self.font_name = font_name
self.face_name = face_name
self.update_callback(context)
self["font_name"] = font_name
self["face_name"] = face_name
self.glyphs_update_callback(self)
text_id: bpy.props.IntProperty()
font: bpy.props.EnumProperty(
items=font_items_callback,
update=font_update_callback,
)
font_name: bpy.props.StringProperty()
face_name: bpy.props.StringProperty()
font_name: bpy.props.StringProperty(
update=glyphs_update_callback
)
face_name: bpy.props.StringProperty(
update=glyphs_update_callback
)
text_object: bpy.props.PointerProperty(type=bpy.types.Object)
text: bpy.props.StringProperty(
update=update_callback
update=glyphs_update_callback
)
letter_spacing: bpy.props.FloatProperty(
update=update_callback,
@ -233,9 +245,9 @@ class ABC3D_text_properties(bpy.types.PropertyGroup):
#TODO: simply, merge, cut cut cut
class ABC3D_data(bpy.types.PropertyGroup):
available_fonts: bpy.props.CollectionProperty(type=ABC3D_available_font, name="name of the collection property")
available_fonts: bpy.props.CollectionProperty(type=ABC3D_available_font, name="Available fonts")
active_font_index: bpy.props.IntProperty()
available_texts: bpy.props.CollectionProperty(type=ABC3D_text_properties, name="")
available_texts: bpy.props.CollectionProperty(type=ABC3D_text_properties, name="Available texts")
def active_text_index_update(self, context):
if self.active_text_index != -1:
o = self.available_texts[self.active_text_index].text_object
@ -320,8 +332,33 @@ class ABC3D_PT_FontList(bpy.types.Panel):
abc3d = scene.abc3d
abc3d_data = scene.abc3d_data
layout.label(text="Loaded Fonts")
layout.label(text="Available Fonts")
layout.template_list("ABC3D_UL_fonts", "", abc3d_data, "available_fonts", abc3d_data, "active_font_index")
if abc3d_data.active_font_index >= 0:
available_font = abc3d_data.available_fonts[abc3d_data.active_font_index]
font_name = available_font.font_name
face_name = available_font.face_name
available_glyphs = sorted(Font.fonts[font_name].faces[face_name].glyphs_in_fontfile)
loaded_glyphs = sorted(Font.fonts[font_name].faces[face_name].loaded_glyphs)
box = layout.box()
box.row().label(text=f"Font Name: {font_name}")
box.row().label(text=f"Face Name: {face_name}")
n = 16
n_rows = int(len(available_glyphs) / n)
box.row().label(text=f"Glyphs:")
for i in range(0, n_rows + 1):
text = ''.join([f"{u}" for ui, u in enumerate(available_glyphs) if ui < (i+1) * n and ui >= i * n])
scale_y = 0.5
row = box.row(); row.scale_y = scale_y
row.label(text=text)
n_rows = int(len(loaded_glyphs) / n)
box.row().label(text=f"Loaded Glyphs:", desription="")
for i in range(0, n_rows + 1):
text = ''.join([f"{u}" for ui, u in enumerate(loaded_glyphs) if ui < (i+1) * n and ui >= i * n])
scale_y = 0.5
row = box.row(); row.scale_y = scale_y
row.label(text=text)
class ABC3D_PT_TextPlacement(bpy.types.Panel):
bl_label = "Place Text"
@ -403,13 +440,17 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
for i in remove_list:
if type(abc3d_data.available_texts[i].text_object) != type(None):
del mom[f"{utils.prefix()}_linked_textobject"]
del mom[f"{utils.prefix()}_font_name"]
del mom[f"{utils.prefix()}_face_name"]
del mom[f"{utils.prefix()}_font_size"]
del mom[f"{utils.prefix()}_letter_spacing"]
del mom[f"{utils.prefix()}_orientation"]
del mom[f"{utils.prefix()}_translation"]
mom = abc3d_data.available_texts[i].text_object
def delif(o, p):
if p in o:
del o[p]
delif(mom,f"{utils.prefix()}_linked_textobject")
delif(mom,f"{utils.prefix()}_font_name")
delif(mom,f"{utils.prefix()}_face_name")
delif(mom,f"{utils.prefix()}_font_size")
delif(mom,f"{utils.prefix()}_letter_spacing")
delif(mom,f"{utils.prefix()}_orientation")
delif(mom,f"{utils.prefix()}_translation")
abc3d_data.available_texts.remove(i)
for i, t in enumerate(abc3d_data.available_texts):
@ -422,7 +463,7 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
if active_text_index != abc3d_data.active_text_index:
abc3d_data.active_text_index = active_text_index
butils.run_in_main_thread(update)
# butils.run_in_main_thread(update)
return True
@ -564,9 +605,18 @@ class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
bl_label = "Loading installed Fonts."
bl_options = {'REGISTER', 'UNDO'}
load_into_memory: bpy.props.BoolProperty(name="load font data into memory",
description="if false, it will load font data on demand",
default=False)
def draw(self, context):
layout = self.layout
layout.label(text="Loading font files can take a long time.")
layout.row().prop(self, "load_into_memory")
if self.load_into_memory:
layout.label(text="Loading font files can take a long time")
layout.label(text="and use a lot of RAM.")
layout.label(text="We recommend not doing this and let us")
layout.label(text="load the font data on demand.")
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
@ -574,7 +624,10 @@ class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
def execute(self, context):
scene = bpy.context.scene
butils.load_installed_fonts()
if self.load_into_memory:
butils.load_installed_fonts()
else:
butils.register_installed_fonts()
butils.ShowMessageBox("Loading Fonts",
'INFO',
"Updating Data Structures.")
@ -744,17 +797,23 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
while text_id == tt.text_id:
text_id = text_id + 1
t = abc3d_data.available_texts.add()
t.text_id = text_id
t.font_name = self.font_name
t.face_name = self.face_name
# If you wish to set a value and not fire an update, set the id property.
# A property defined via bpy.props for example ob.prop is stored as ob["prop"] once set to non default.
t['text_id'] = text_id
t['font_name'] = self.font_name
t['face_name'] = self.face_name
t.text_object = selected
t.text = self.text
t.letter_spacing = self.letter_spacing
t.font_size = self.font_size
t.translation = self.translation
t.orientation = self.orientation
t.distribution_type = distribution_type
t['text'] = self.text
t['letter_spacing'] = self.letter_spacing
t['font_size'] = self.font_size
t['translation'] = self.translation
t['orientation'] = self.orientation
t['distribution_type'] = distribution_type
butils.prepare_text(t.font_name,
t.face_name,
t.text)
butils.set_text_on_curve(t)
else:
butils.ShowMessageBox(
title="No object selected",
@ -1134,6 +1193,8 @@ class ABC3D_OT_Reporter(bpy.types.Operator):
return {'FINISHED'}
classes = (
bimport.ImportGLTF2,
bimport.GetFontFacesInFile,
ABC3D_addonPreferences,
ABC3D_available_font,
ABC3D_glyph_properties,
@ -1169,7 +1230,7 @@ def load_handler(self, dummy):
if not bpy.app.timers.is_registered(butils.execute_queued_functions):
bpy.app.timers.register(butils.execute_queued_functions)
butils.run_in_main_thread(butils.update_available_fonts)
# butils.run_in_main_thread(bpy.ops.abc3d.load_installed_fonts)
butils.run_in_main_thread(bpy.ops.abc3d.load_installed_fonts)
def load_handler_unload():
if bpy.app.timers.is_registered(butils.execute_queued_functions):
@ -1180,10 +1241,6 @@ def on_frame_changed(self, dummy):
for t in bpy.context.scene.abc3d_data.available_texts:
# TODO PERFORMANCE: only on demand
butils.set_text_on_curve(t)
# for i, t in enumerate(bpy.context.scene.abc3d_data.available_texts):
# # TODO PERFORMANCE: only on demand
# # butils.set_text_on_curve(t)
# pass
def register():
for cls in classes: