font path adventures with Mac OS
This commit is contained in:
parent
edb2c8cb8b
commit
3631ac8e49
2 changed files with 71 additions and 89 deletions
158
__init__.py
158
__init__.py
|
@ -93,60 +93,11 @@ class ABC3D_addonPreferences(bpy.types.AddonPreferences):
|
||||||
layout.prop(self, "assets_dir")
|
layout.prop(self, "assets_dir")
|
||||||
|
|
||||||
|
|
||||||
class ABC3D_settings(bpy.types.PropertyGroup):
|
|
||||||
font_path: bpy.props.StringProperty(
|
|
||||||
name="Font path",
|
|
||||||
description="Load a *.glb or *.gltf fontfile from disk",
|
|
||||||
default="",
|
|
||||||
maxlen=1024,
|
|
||||||
subtype="FILE_PATH")
|
|
||||||
import_infix: bpy.props.StringProperty(
|
|
||||||
name="Font name import infix",
|
|
||||||
description="The infix which all font objects to import have. obj name: 'A_NM_Origin_Tender' -> infix: '_NM_Origin_Tender'",
|
|
||||||
default="_NM_",
|
|
||||||
maxlen=1024,
|
|
||||||
)
|
|
||||||
text: bpy.props.StringProperty(
|
|
||||||
name="Text",
|
|
||||||
description="The text.",
|
|
||||||
default="HELLO",
|
|
||||||
maxlen=1024,
|
|
||||||
)
|
|
||||||
target_object: bpy.props.PointerProperty(
|
|
||||||
name="The Target Object",
|
|
||||||
description="The target, which will be populated by character children of text.",
|
|
||||||
type=bpy.types.Object,
|
|
||||||
)
|
|
||||||
letter_spacing: bpy.props.FloatProperty(
|
|
||||||
name="Letter Spacing",
|
|
||||||
description="Letter Spacing",
|
|
||||||
default=0.0,
|
|
||||||
)
|
|
||||||
font_size: bpy.props.FloatProperty(
|
|
||||||
name="Font Size",
|
|
||||||
default=1.0,
|
|
||||||
subtype='NONE',
|
|
||||||
)
|
|
||||||
translation: bpy.props.FloatVectorProperty(
|
|
||||||
name="Translation",
|
|
||||||
default=(0.0, 0.0, 0.0),
|
|
||||||
subtype='TRANSLATION',
|
|
||||||
)
|
|
||||||
orientation: bpy.props.FloatVectorProperty(
|
|
||||||
name="Orientation",
|
|
||||||
default=(1.5707963267948966, 0.0, 0.0), # 90 degrees in radians
|
|
||||||
subtype='EULER',
|
|
||||||
)
|
|
||||||
offset: bpy.props.FloatProperty(
|
|
||||||
name="Offset",
|
|
||||||
default=0.0,
|
|
||||||
subtype='NONE',
|
|
||||||
)
|
|
||||||
|
|
||||||
class ABC3D_available_font(bpy.types.PropertyGroup):
|
class ABC3D_available_font(bpy.types.PropertyGroup):
|
||||||
font_name: bpy.props.StringProperty(name="")
|
font_name: bpy.props.StringProperty(name="")
|
||||||
face_name: bpy.props.StringProperty(name="")
|
face_name: bpy.props.StringProperty(name="")
|
||||||
|
|
||||||
|
|
||||||
class ABC3D_glyph_properties(bpy.types.PropertyGroup):
|
class ABC3D_glyph_properties(bpy.types.PropertyGroup):
|
||||||
glyph_id: bpy.props.StringProperty(maxlen=1)
|
glyph_id: bpy.props.StringProperty(maxlen=1)
|
||||||
glyph_object: bpy.props.PointerProperty(type=bpy.types.Object)
|
glyph_object: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||||
|
@ -282,6 +233,20 @@ class ABC3D_data(bpy.types.PropertyGroup):
|
||||||
|
|
||||||
active_text_index: bpy.props.IntProperty(update=active_text_index_update)
|
active_text_index: bpy.props.IntProperty(update=active_text_index_update)
|
||||||
|
|
||||||
|
# def font_path_update_callback(self, context):
|
||||||
|
# butils.ShowMessageBox("Friendly Reminder", message="do not forget to click on 'Install new font'")
|
||||||
|
# bpy.ops.abc3d.install_font()
|
||||||
|
|
||||||
|
# stupid hack for Mac OS
|
||||||
|
font_path: bpy.props.StringProperty(
|
||||||
|
name="Font path",
|
||||||
|
description="Install a *.glb or *.gltf fontfile from disk",
|
||||||
|
default="",
|
||||||
|
maxlen=1024,
|
||||||
|
# update=font_path_update_callback,
|
||||||
|
subtype="FILE_PATH")
|
||||||
|
|
||||||
|
|
||||||
class ABC3D_UL_fonts(bpy.types.UIList):
|
class ABC3D_UL_fonts(bpy.types.UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||||
layout.label(text=f"{index}: {item.font_name} {item.face_name}") # avoids renaming the item by accident
|
layout.label(text=f"{index}: {item.font_name} {item.face_name}") # avoids renaming the item by accident
|
||||||
|
@ -313,27 +278,25 @@ class ABC3D_PT_Panel(bpy.types.Panel):
|
||||||
layout.row().label(text='no fonts loaded yet')
|
layout.row().label(text='no fonts loaded yet')
|
||||||
|
|
||||||
layout.operator(f"{__name__}.load_installed_fonts", text="load installed fonts", icon=icon)
|
layout.operator(f"{__name__}.load_installed_fonts", text="load installed fonts", icon=icon)
|
||||||
|
layout.row().prop(context.scene.abc3d_data, "font_path")
|
||||||
|
layout.row().operator(f"{__name__}.install_font", text='Install new font')
|
||||||
|
|
||||||
|
|
||||||
class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
|
# class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
|
||||||
bl_label = "Install 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"
|
||||||
bl_region_type = "UI"
|
# bl_region_type = "UI"
|
||||||
bl_options = {"DEFAULT_CLOSED"}
|
|
||||||
|
|
||||||
def draw(self, context):
|
# def draw(self, context):
|
||||||
layout = self.layout
|
# layout = self.layout
|
||||||
wm = context.window_manager
|
# wm = context.window_manager
|
||||||
scene = context.scene
|
# scene = context.scene
|
||||||
|
|
||||||
abc3d = scene.abc3d
|
# abc3d_data = scene.abc3d_data
|
||||||
abc3d_data = scene.abc3d_data
|
|
||||||
|
|
||||||
layout.label(text="Install FontFile:")
|
# layout.row().operator(f"{__name__}.install_font", text='Install new font')
|
||||||
layout.row().prop(abc3d, "font_path")
|
|
||||||
layout.row().operator(f"{__name__}.install_font", text='Install')
|
|
||||||
|
|
||||||
|
|
||||||
class ABC3D_PT_FontList(bpy.types.Panel):
|
class ABC3D_PT_FontList(bpy.types.Panel):
|
||||||
|
@ -348,7 +311,6 @@ class ABC3D_PT_FontList(bpy.types.Panel):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
|
|
||||||
layout.label(text="Available Fonts")
|
layout.label(text="Available Fonts")
|
||||||
|
@ -403,7 +365,6 @@ class ABC3D_PT_TextPlacement(bpy.types.Panel):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
|
|
||||||
placerow = layout.row()
|
placerow = layout.row()
|
||||||
|
@ -425,7 +386,6 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(self, context):
|
def poll(self, context):
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
# TODO: update available_texts
|
# TODO: update available_texts
|
||||||
def update():
|
def update():
|
||||||
|
@ -495,7 +455,6 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
|
|
||||||
layout.label(text="Text Objects")
|
layout.label(text="Text Objects")
|
||||||
|
@ -515,7 +474,6 @@ class ABC3D_PT_FontCreation(bpy.types.Panel):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
|
|
||||||
layout.row().operator(f"{__name__}.create_font_from_objects", text='Create/Extend Font')
|
layout.row().operator(f"{__name__}.create_font_from_objects", text='Create/Extend Font')
|
||||||
|
@ -580,7 +538,6 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
abc3d = scene.abc3d
|
|
||||||
abc3d_data = scene.abc3d_data
|
abc3d_data = scene.abc3d_data
|
||||||
|
|
||||||
props = self.get_active_text_properties()
|
props = self.get_active_text_properties()
|
||||||
|
@ -609,6 +566,20 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
||||||
bl_label = "Load Font"
|
bl_label = "Load Font"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
def font_path_update_callback(self, context):
|
||||||
|
if os.path.exists(self.font_path):
|
||||||
|
print(f"{self.font_path} does exist")
|
||||||
|
else:
|
||||||
|
print(f"{self.font_path} does not exist")
|
||||||
|
|
||||||
|
font_path: bpy.props.StringProperty(
|
||||||
|
name="Font path",
|
||||||
|
description="Install a *.glb or *.gltf fontfile from disk",
|
||||||
|
default="",
|
||||||
|
maxlen=1024,
|
||||||
|
# update=font_path_update_callback,
|
||||||
|
subtype="FILE_PATH")
|
||||||
|
|
||||||
install_in_assets: bpy.props.BoolProperty(
|
install_in_assets: bpy.props.BoolProperty(
|
||||||
name="install in assets",
|
name="install in assets",
|
||||||
description="install the font in the assets directory of the addon",
|
description="install the font in the assets directory of the addon",
|
||||||
|
@ -620,7 +591,9 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
||||||
default=False)
|
default=False)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
abc3d_data = context.scene.abc3d_data
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
# layout.row().prop(self, "font_path") # crashes on Mac OS?
|
||||||
layout.row().prop(self, "install_in_assets")
|
layout.row().prop(self, "install_in_assets")
|
||||||
if not self.install_in_assets and not self.load_into_memory:
|
if not self.install_in_assets and not self.load_into_memory:
|
||||||
layout.label(text="If the fontfile is not installed,")
|
layout.label(text="If the fontfile is not installed,")
|
||||||
|
@ -634,27 +607,42 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
||||||
layout.label(text="load the font data on demand.")
|
layout.label(text="load the font data on demand.")
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
|
abc3d_data = context.scene.abc3d_data
|
||||||
|
self.font_path = abc3d_data.font_path
|
||||||
|
if not os.path.exists(self.font_path):
|
||||||
|
bpy.app.timers.register(lambda: butils.ShowMessageBox(
|
||||||
|
title=f"{__name__} Warning",
|
||||||
|
icon="ERROR",
|
||||||
|
message=[
|
||||||
|
f"We believe the font path ({self.font_path}) does not exist.",
|
||||||
|
f"Did you select your fontfile in the field above the 'Install new font'-button?",
|
||||||
|
],
|
||||||
|
), first_interval=0.1)
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
|
|
||||||
if not os.path.exists(scene.abc3d.font_path):
|
abc3d_data = context.scene.abc3d_data
|
||||||
|
if not os.path.exists(self.font_path):
|
||||||
butils.ShowMessageBox(
|
butils.ShowMessageBox(
|
||||||
title=f"{__name__} Warning",
|
title=f"{__name__} Warning",
|
||||||
icon="ERROR",
|
icon="ERROR",
|
||||||
message=f"We believe the font path ({scene.abc3d.font_path}) does not exist.",
|
message=[
|
||||||
|
f"Could not install font.",
|
||||||
|
f"We believe the font path ({self.font_path}) does not exist.",
|
||||||
|
f"If this is an error, please let us know.",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
if self.install_in_assets:
|
if self.install_in_assets:
|
||||||
preferences = getPreferences(context)
|
preferences = getPreferences(context)
|
||||||
filename = os.path.basename(scene.abc3d.font_path)
|
filename = os.path.basename(self.font_path)
|
||||||
target = os.path.join(preferences.assets_dir, "fonts", filename)
|
target = os.path.join(preferences.assets_dir, "fonts", filename)
|
||||||
print(f"installing {scene.abc3d.font_path} -> {target}")
|
|
||||||
import shutil
|
import shutil
|
||||||
os.makedirs(os.path.dirname(target), exist_ok=True)
|
os.makedirs(os.path.dirname(target), exist_ok=True)
|
||||||
shutil.copyfile(scene.abc3d.font_path, target)
|
shutil.copyfile(self.font_path, target)
|
||||||
# def register_load(target, load=False):
|
# def register_load(target, load=False):
|
||||||
# print(f"registering installed fonts")
|
# print(f"registering installed fonts")
|
||||||
# bpy.app.timers.register(lambda: register_load(target, self.load_into_memory), first_interval=5)
|
# bpy.app.timers.register(lambda: register_load(target, self.load_into_memory), first_interval=5)
|
||||||
|
@ -663,9 +651,9 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
||||||
butils.load_font_from_filepath(target)
|
butils.load_font_from_filepath(target)
|
||||||
butils.update_available_fonts()
|
butils.update_available_fonts()
|
||||||
else:
|
else:
|
||||||
butils.register_font_from_filepath(scene.abc3d.font_path)
|
butils.register_font_from_filepath(self.font_path)
|
||||||
if self.load_into_memory:
|
if self.load_into_memory:
|
||||||
butils.load_font_from_filepath(scene.abc3d.font_path)
|
butils.load_font_from_filepath(self.font_path)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
@ -692,6 +680,7 @@ class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
print("EXECUTE LOAD INSTALLED FONTS")
|
||||||
scene = bpy.context.scene
|
scene = bpy.context.scene
|
||||||
|
|
||||||
if self.load_into_memory:
|
if self.load_into_memory:
|
||||||
|
@ -907,9 +896,6 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
|
||||||
|
|
||||||
selected = bpy.context.view_layer.objects.active
|
selected = bpy.context.view_layer.objects.active
|
||||||
|
|
||||||
# if abc3d.target_object:
|
|
||||||
# selected = abc3d.target_object
|
|
||||||
|
|
||||||
if selected:
|
if selected:
|
||||||
# font = abc3d_data.available_fonts[abc3d_data.active_font_index]
|
# font = abc3d_data.available_fonts[abc3d_data.active_font_index]
|
||||||
# font_name = font.font_name
|
# font_name = font.font_name
|
||||||
|
@ -1181,7 +1167,7 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
||||||
if fontcollection is None:
|
if fontcollection is None:
|
||||||
fontcollection = bpy.data.collections.new("ABC3D")
|
fontcollection = bpy.data.collections.new("ABC3D")
|
||||||
|
|
||||||
ifxsplit = abc3d.import_infix.split('_')
|
ifxsplit = self.import_infix.split('_')
|
||||||
# if len(ifxsplit) != 4:
|
# if len(ifxsplit) != 4:
|
||||||
|
|
||||||
# font_name = f"{ifxsplit[1]}_{ifxsplit[2]}"
|
# font_name = f"{ifxsplit[1]}_{ifxsplit[2]}"
|
||||||
|
@ -1207,7 +1193,6 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
||||||
|
|
||||||
if butils.is_mesh(o) and not butils.is_metrics_object(o):
|
if butils.is_mesh(o) and not butils.is_metrics_object(o):
|
||||||
uc = o.users_collection
|
uc = o.users_collection
|
||||||
# regex = f"{abc3d.import_infix}(.)*"
|
|
||||||
if self.fix_common_misspellings:
|
if self.fix_common_misspellings:
|
||||||
o.name = Font.fix_glyph_name_misspellings(o.name)
|
o.name = Font.fix_glyph_name_misspellings(o.name)
|
||||||
# name = re.sub(regex, "", o.name)
|
# name = re.sub(regex, "", o.name)
|
||||||
|
@ -1332,11 +1317,10 @@ classes = (
|
||||||
ABC3D_glyph_properties,
|
ABC3D_glyph_properties,
|
||||||
ABC3D_text_properties,
|
ABC3D_text_properties,
|
||||||
ABC3D_data,
|
ABC3D_data,
|
||||||
ABC3D_settings,
|
|
||||||
ABC3D_UL_fonts,
|
ABC3D_UL_fonts,
|
||||||
ABC3D_UL_texts,
|
ABC3D_UL_texts,
|
||||||
ABC3D_PT_Panel,
|
ABC3D_PT_Panel,
|
||||||
ABC3D_PT_LoadFontPanel,
|
# ABC3D_PT_LoadFontPanel,
|
||||||
ABC3D_PT_FontList,
|
ABC3D_PT_FontList,
|
||||||
ABC3D_PT_TextPlacement,
|
ABC3D_PT_TextPlacement,
|
||||||
ABC3D_PT_TextManagement,
|
ABC3D_PT_TextManagement,
|
||||||
|
@ -1378,7 +1362,6 @@ def on_frame_changed(self, dummy):
|
||||||
def register():
|
def register():
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
bpy.utils.register_class(cls)
|
bpy.utils.register_class(cls)
|
||||||
bpy.types.Scene.abc3d = bpy.props.PointerProperty(type=ABC3D_settings)
|
|
||||||
bpy.types.Scene.abc3d_data = bpy.props.PointerProperty(type=ABC3D_data)
|
bpy.types.Scene.abc3d_data = bpy.props.PointerProperty(type=ABC3D_data)
|
||||||
# bpy.types.Object.__del__ = lambda self: print(f"Bye {self.name}")
|
# bpy.types.Object.__del__ = lambda self: print(f"Bye {self.name}")
|
||||||
print(f"REGISTER {bl_info['name']}")
|
print(f"REGISTER {bl_info['name']}")
|
||||||
|
@ -1413,7 +1396,6 @@ def unregister():
|
||||||
if on_frame_changed in bpy.app.handlers.frame_change_post:
|
if on_frame_changed in bpy.app.handlers.frame_change_post:
|
||||||
bpy.app.handlers.frame_change_post.remove(on_frame_changed)
|
bpy.app.handlers.frame_change_post.remove(on_frame_changed)
|
||||||
|
|
||||||
del bpy.types.Scene.abc3d
|
|
||||||
del bpy.types.Scene.abc3d_data
|
del bpy.types.Scene.abc3d_data
|
||||||
print(f"UNREGISTER {bl_info['name']}")
|
print(f"UNREGISTER {bl_info['name']}")
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,7 @@ def register_font_from_filepath(filepath):
|
||||||
|
|
||||||
def load_font_from_filepath(filepath, glyphs="", font_name="", face_name=""):
|
def load_font_from_filepath(filepath, glyphs="", font_name="", face_name=""):
|
||||||
if not filepath.endswith(".glb") and not filepath.endswith(".gltf"):
|
if not filepath.endswith(".glb") and not filepath.endswith(".gltf"):
|
||||||
ShowMessageBox(f"{bl_info['name']} Font loading error", 'ERROR', f"Filepath({filepath}) is not a *.glb or *.gltf file")
|
ShowMessageBox(f"Font loading error", 'ERROR', f"Filepath({filepath}) is not a *.glb or *.gltf file")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
marker_property = "font_import"
|
marker_property = "font_import"
|
||||||
|
|
Loading…
Reference in a new issue