load installed fonts, fix some minor loading issues

This commit is contained in:
themancalledjakob 2024-08-14 13:39:47 +02:00
parent 8ce5e6c816
commit 0bf80e01b2
3 changed files with 69 additions and 20 deletions

View file

@ -262,11 +262,16 @@ class ABC3D_PT_Panel(bpy.types.Panel):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text=f"{__name__} panel") icon = 'NONE'
if len(context.scene.abc3d_data.available_fonts) == 0:
icon = 'ERROR'
layout.row().label(text='no fonts loaded yet')
layout.operator(f"{__name__}.load_installed_fonts", text="load installed fonts", icon=icon)
class ABC3D_PT_LoadFontPanel(bpy.types.Panel): class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
bl_label = "Load a new font" bl_label = "Install a new font"
bl_parent_id = "ABC3D_PT_Panel" bl_parent_id = "ABC3D_PT_Panel"
bl_category = "ABC3D" bl_category = "ABC3D"
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
@ -281,9 +286,9 @@ class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
abc3d = scene.abc3d abc3d = scene.abc3d
abc3d_data = scene.abc3d_data abc3d_data = scene.abc3d_data
layout.label(text="Load FontFile:") layout.label(text="Install FontFile:")
layout.row().prop(abc3d, "font_path") layout.row().prop(abc3d, "font_path")
layout.row().operator('abc3d.loadfont', text='Load Font') layout.row().operator(f"{__name__}.loadfont", text='Load Font')
class ABC3D_PT_FontList(bpy.types.Panel): class ABC3D_PT_FontList(bpy.types.Panel):
@ -497,13 +502,6 @@ class ABC3D_OT_LoadFont(bpy.types.Operator):
def execute(self, context): def execute(self, context):
scene = bpy.context.scene scene = bpy.context.scene
butils.ShowMessageBox(
title=f"{__name__} Warning",
icon="ERROR",
message=f"We believe this functionality is currently not available.",
)
return {'CANCELLED'}
if not os.path.exists(scene.abc3d.font_path): if not os.path.exists(scene.abc3d.font_path):
butils.ShowMessageBox( butils.ShowMessageBox(
title=f"{__name__} Warning", title=f"{__name__} Warning",
@ -516,6 +514,27 @@ class ABC3D_OT_LoadFont(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
"""Load installed fontfiles from datapath."""
bl_idname = f"{__name__}.load_installed_fonts"
bl_label = "Loading installed Fonts."
bl_options = {'REGISTER', 'UNDO'}
def draw(self, context):
layout = self.layout
layout.label(text="Loading font files can take a long time.")
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def execute(self, context):
scene = bpy.context.scene
butils.load_installed_fonts()
butils.update_available_fonts()
return {'FINISHED'}
class ABC3D_OT_AddDefaultMetrics(bpy.types.Operator): class ABC3D_OT_AddDefaultMetrics(bpy.types.Operator):
"""Add default metrics to selected objects""" """Add default metrics to selected objects"""
bl_idname = f"{__name__}.add_default_metrics" bl_idname = f"{__name__}.add_default_metrics"
@ -735,9 +754,12 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
for obj in fontcollection.objects: for obj in fontcollection.objects:
if obj["font_name"] == selected_font.font_name: if obj["font_name"] == selected_font.font_name:
if not butils.is_metrics_object(obj): if not butils.is_metrics_object(obj):
# butils.add_faces_to_metrics(obj)
obj.select_set(True) obj.select_set(True)
export_objects.append(obj) export_objects.append(obj)
else:
obj.select_set(True)
butils.add_faces_to_metrics(obj)
export_objects.append(obj)
context_override = bpy.context.copy() context_override = bpy.context.copy()
context_override["selected_objects"] = list(export_objects) context_override["selected_objects"] = list(export_objects)
@ -1019,6 +1041,7 @@ classes = (
ABC3D_PT_TextManagement, ABC3D_PT_TextManagement,
ABC3D_PT_FontCreation, ABC3D_PT_FontCreation,
ABC3D_PT_TextPropertiesPanel, ABC3D_PT_TextPropertiesPanel,
ABC3D_OT_LoadInstalledFonts,
ABC3D_OT_AddDefaultMetrics, ABC3D_OT_AddDefaultMetrics,
ABC3D_OT_RemoveMetrics, ABC3D_OT_RemoveMetrics,
ABC3D_OT_AlignMetricsToActiveObject, ABC3D_OT_AlignMetricsToActiveObject,
@ -1038,6 +1061,7 @@ def load_handler(self, dummy):
if not bpy.app.timers.is_registered(butils.execute_queued_functions): if not bpy.app.timers.is_registered(butils.execute_queued_functions):
bpy.app.timers.register(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(butils.update_available_fonts)
# butils.run_in_main_thread(bpy.ops.abc3d.load_installed_fonts)
def load_handler_unload(): def load_handler_unload():
if bpy.app.timers.is_registered(butils.execute_queued_functions): if bpy.app.timers.is_registered(butils.execute_queued_functions):
@ -1071,9 +1095,11 @@ def register():
bpy.app.handlers.frame_change_post.append(on_frame_changed) bpy.app.handlers.frame_change_post.append(on_frame_changed)
butils.run_in_main_thread(butils.clear_available_fonts) butils.run_in_main_thread(butils.clear_available_fonts)
butils.run_in_main_thread(butils.load_available_fonts) # butils.run_in_main_thread(butils.load_installed_fonts)
butils.run_in_main_thread(butils.update_available_fonts) butils.run_in_main_thread(butils.update_available_fonts)
# bpy.ops.abc3d.load_installed_fonts()
Font.name_to_glyph_d = Font.generate_name_to_glyph_d() Font.name_to_glyph_d = Font.generate_name_to_glyph_d()
def unregister(): def unregister():

View file

@ -419,7 +419,7 @@ def load_font_from_filepath(filepath):
glyph_id = o["glyph"] glyph_id = o["glyph"]
font_name = o["font_name"] font_name = o["font_name"]
face_name = o["face_name"] face_name = o["face_name"]
ShowMessageBox("Loading Font", "INFO", f"adding glyph {glyph_id} for {font_name} {face_name}") # ShowMessageBox("Loading Font", "INFO", f"adding glyph {glyph_id} for {font_name} {face_name}")
print(f"adding glyph {glyph_id} for {font_name} {face_name}") print(f"adding glyph {glyph_id} for {font_name} {face_name}")
glyph_obj = move_in_fontcollection( glyph_obj = move_in_fontcollection(
o, o,
@ -486,15 +486,13 @@ def getPreferences(context):
def clear_available_fonts(): def clear_available_fonts():
bpy.context.scene.abc3d_data.available_fonts.clear() bpy.context.scene.abc3d_data.available_fonts.clear()
def load_available_fonts(): def load_installed_fonts():
preferences = getPreferences(bpy.context) preferences = getPreferences(bpy.context)
print(f"assets folder: {preferences.assets_dir}")
font_dir = f"{preferences.assets_dir}/fonts" font_dir = f"{preferences.assets_dir}/fonts"
for file in os.listdir(font_dir): for file in os.listdir(font_dir):
if file.endswith(".glb") or file.endswith(".gltf"): if file.endswith(".glb") or file.endswith(".gltf"):
font_path = os.path.join(font_dir, file) font_path = os.path.join(font_dir, file)
ShowMessageBox("Loading Font", "INFO", f"loading font from {font_path}") # ShowMessageBox("Loading Font", "INFO", f"loading font from {font_path}")
print(f"loading font from {font_path}") print(f"loading font from {font_path}")
for f in bpy.context.scene.abc3d_data.available_fonts.values(): for f in bpy.context.scene.abc3d_data.available_fonts.values():
print(f"available font: {f.font_name} {f.face_name}") print(f"available font: {f.font_name} {f.face_name}")
@ -555,7 +553,7 @@ def is_mesh(o):
return type(o.data) == bpy.types.Mesh return type(o.data) == bpy.types.Mesh
def is_metrics_object(o): def is_metrics_object(o):
return (re.match("[\w]*_metrics$", o.name) != None or re.match("[\w]*_metrics.[\d]{3}$", o.name) != None) and is_mesh(o) return (re.match(".*_metrics$", o.name) != None or re.match(".*_metrics.[\d]{3}$", o.name) != None) and is_mesh(o)
def is_glyph(o): def is_glyph(o):
try: try:
@ -757,6 +755,15 @@ def add_metrics_obj_from_bound_box(glyph, bound_box=None):
obj["face_name"] = glyph["face_name"] obj["face_name"] = glyph["face_name"]
obj["glyph"] = glyph["glyph"] obj["glyph"] = glyph["glyph"]
obj["type"] = "metrics" obj["type"] = "metrics"
# remove already existing metrics
remove_metrics = []
for c in glyph.children:
if is_metrics_object(c):
remove_metrics.append(c)
if len(remove_metrics) > 0:
completely_delete_objects(remove_metrics)
col = glyph.users_collection[0] col = glyph.users_collection[0]
col.objects.link(obj) col.objects.link(obj)
# bpy.context.view_layer.objects.active = obj # bpy.context.view_layer.objects.active = obj
@ -784,6 +791,7 @@ def add_metrics_obj_from_bound_box(glyph, bound_box=None):
def add_faces_to_metrics(obj): def add_faces_to_metrics(obj):
mesh = bpy.data.meshes.new(f"{obj.name}") # add the new mesh mesh = bpy.data.meshes.new(f"{obj.name}") # add the new mesh
print(f"add_faces_to_metrics for {obj.name}")
bound_box = bound_box_as_array(obj.bound_box) bound_box = bound_box_as_array(obj.bound_box)
verts = [bound_box[0], verts = [bound_box[0],
bound_box[1], bound_box[1],

View file

@ -1,4 +1,3 @@
import time import time
import datetime import datetime
from mathutils import ( from mathutils import (
@ -19,6 +18,22 @@ def mapRange(in_value, in_min, in_max, out_min, out_max, clamp=False):
return max(out_max, min(out_min, output)) return max(out_max, min(out_min, output))
else: else:
return output return output
import warnings
import functools
def deprecated(func):
"""This is a decorator which can be used to mark functions
as deprecated. It will result in a warning being emitted
when the function is used."""
@functools.wraps(func)
def new_func(*args, **kwargs):
warnings.simplefilter('always', DeprecationWarning) # turn off filter
warnings.warn("Call to deprecated function {}.".format(func.__name__),
category=DeprecationWarning,
stacklevel=2)
warnings.simplefilter('default', DeprecationWarning) # reset filter
return func(*args, **kwargs)
return new_func
# # Evaluate a bezier curve for the parameter 0<=t<=1 along its length # # Evaluate a bezier curve for the parameter 0<=t<=1 along its length
# def evaluateBezierPoint(p1, h1, h2, p2, t): # def evaluateBezierPoint(p1, h1, h2, p2, t):