cosmetics

This commit is contained in:
themancalledjakob 2024-11-05 16:01:15 +01:00
parent 4a10584710
commit 30251a635f

View file

@ -4,6 +4,14 @@
A 3D font helper
"""
import os
from bpy.app.handlers import persistent
from bpy.types import Panel
import functools
import io
import bpy
import importlib
bl_info = {
"name": "ABC3D",
"author": "Jakob Schlötter, Studio Pointer*",
@ -18,10 +26,7 @@ bl_info = {
# when registering
# handy for development
# first import dependencies for the method
import importlib
# then import dependencies for our addon
if "bpy" in locals():
if "Font" in locals():
importlib.reload(Font)
importlib.reload(utils)
importlib.reload(butils)
@ -34,20 +39,6 @@ else:
from . import bimport
from . import addon_updater_ops
import bpy
import math
import mathutils
import io
import functools
from bpy.types import Panel
from bpy.app.handlers import persistent
from random import uniform
import time
import datetime
import os
import re
def getPreferences(context):
preferences = context.preferences
@ -165,15 +156,15 @@ class ABC3D_text_properties(bpy.types.PropertyGroup):
if len(d.available_fonts) > 0:
if len(d.available_fonts) > d.active_text_index:
f = d.available_fonts[d.active_text_index]
return 0 #f"{f.font_name} {f.face_name}"
return 0 # f"{f.font_name} {f.face_name}"
else:
f = d.available_fonts[0]
return 0 #f"{f.font_name} {f.face_name}"
return 0 # f"{f.font_name} {f.face_name}"
if type(self.font_name) != type(None) and type(self.face_name) != type(None):
return 0 #f"{self.font_name} {self.face_name}"
return 0 # f"{self.font_name} {self.face_name}"
else:
return 0 #""
return 0 # ""
def glyphs_update_callback(self, context):
butils.prepare_text(self.font_name,
@ -250,9 +241,13 @@ class ABC3D_text_properties(bpy.types.PropertyGroup):
distribution_type: bpy.props.StringProperty()
glyphs: bpy.props.CollectionProperty(type=ABC3D_glyph_properties)
#TODO: simply, merge, cut cut cut
# TODO: simply, merge, cut cut cut
class ABC3D_data(bpy.types.PropertyGroup):
available_fonts: bpy.props.CollectionProperty(type=ABC3D_available_font, name="Available fonts")
available_fonts: bpy.props.CollectionProperty(
type=ABC3D_available_font, name="Available fonts")
def active_font_index_update(self, context):
if len(self.available_fonts) <= self.active_font_index:
self.active_font_index = len(self.available_fonts) - 1
@ -261,14 +256,16 @@ class ABC3D_data(bpy.types.PropertyGroup):
default=-1,
update=active_font_index_update,
)
available_texts: bpy.props.CollectionProperty(type=ABC3D_text_properties, name="Available texts")
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
# active_text_index changed. so let's update the selection
# check if it is already selected
# or perhaps one of the glyphs
if not o.select_get() and not len([ c for c in o.children if c.select_get() ]) > 0:
if not o.select_get() and not len([c for c in o.children if c.select_get()]) > 0:
bpy.ops.object.select_all(action="DESELECT")
o.select_set(True)
bpy.context.view_layer.objects.active = o
@ -297,20 +294,24 @@ class ABC3D_data(bpy.types.PropertyGroup):
class ABC3D_UL_fonts(bpy.types.UIList):
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
# avoids renaming the item by accident
layout.label(text=f"{index}: {item.font_name} {item.face_name}")
def invoke(self, context, event):
pass
class ABC3D_UL_texts(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
split = layout.split(factor=0.3)
split.label(text="Id: %d" % (item.text_id))
split.label(text=f"{item.text}") # avoids renaming the item by accident
# avoids renaming the item by accident
split.label(text=f"{item.text}")
def invoke(self, context, event):
pass
class ABC3D_PT_Panel(bpy.types.Panel):
bl_label = f"{__name__} panel"
bl_category = "ABC3D"
@ -325,8 +326,10 @@ class ABC3D_PT_Panel(bpy.types.Panel):
icon = 'ERROR'
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__}.open_asset_directory", text="open asset directory", icon='FILEBROWSER')
layout.operator(f"{__name__}.load_installed_fonts",
text="load installed fonts", icon=icon)
layout.operator(f"{__name__}.open_asset_directory",
text="open asset directory", icon='FILEBROWSER')
class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
@ -365,13 +368,16 @@ class ABC3D_PT_FontList(bpy.types.Panel):
abc3d_data = scene.abc3d_data
layout.label(text="Available Fonts")
layout.template_list("ABC3D_UL_fonts", "", abc3d_data, "available_fonts", abc3d_data, "active_font_index")
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)
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}")
@ -380,20 +386,26 @@ class ABC3D_PT_FontList(bpy.types.Panel):
box.row().label(text=f"Glyphs:")
subbox = box.box()
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])
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 = subbox.row(); row.scale_y = scale_y; row.alignment = 'CENTER'
row = subbox.row()
row.scale_y = scale_y
row.alignment = 'CENTER'
row.label(text=text)
n_rows = int(len(loaded_glyphs) / n)
box.row().label(text=f"Loaded/Used Glyphs:")
subbox = box.box()
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])
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 = subbox.row(); row.scale_y = scale_y
row = subbox.row()
row.scale_y = scale_y
row.label(text=text)
row = layout.row()
oper = row.operator(f"{__name__}.load_font", text='Load all glyphs in memory')
oper = row.operator(f"{__name__}.load_font",
text='Load all glyphs in memory')
oper.font_name = font_name
oper.face_name = face_name
@ -429,6 +441,7 @@ class ABC3D_PT_TextPlacement(bpy.types.Panel):
layout.label(text="Cannot place Text.")
layout.label(text="Select a curve as active object.")
class ABC3D_PT_TextManagement(bpy.types.Panel):
bl_label = "Text Management"
bl_parent_id = "ABC3D_PT_Panel"
@ -443,6 +456,7 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
scene = context.scene
abc3d_data = scene.abc3d_data
# TODO: update available_texts
def update():
if bpy.context.screen.is_animation_playing:
return
@ -461,7 +475,8 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
# these might be there in t.glyphs, but linked to removed objects
# or they might be lost
if type(next((g for g in t.glyphs if type(g.glyph_object) == type(None)), None)) == type(None):
g = next((g for g in t.glyphs if type(g.glyph_object) == type(None)), None)
g = next((g for g in t.glyphs if type(
g.glyph_object) == type(None)), None)
# for g in t.glyphs:
# if type(g) == type(None):
# print("IS NONE")
@ -478,17 +493,18 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
for i in remove_list:
if type(abc3d_data.available_texts[i].text_object) != type(None):
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")
delif(mom,f"{utils.prefix()}_offset")
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")
delif(mom, f"{utils.prefix()}_offset")
abc3d_data.available_texts.remove(i)
for i, t in enumerate(abc3d_data.available_texts):
@ -513,8 +529,11 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
abc3d_data = scene.abc3d_data
layout.label(text="Text Objects")
layout.template_list("ABC3D_UL_texts", "", abc3d_data, "available_texts", abc3d_data, "active_text_index")
layout.row().operator(f"{__name__}.remove_text", text="Remove Textobject")
layout.template_list("ABC3D_UL_texts", "", abc3d_data,
"available_texts", abc3d_data, "active_text_index")
layout.row().operator(
f"{__name__}.remove_text", text="Remove Textobject")
class ABC3D_PT_FontCreation(bpy.types.Panel):
bl_label = "Font Creation"
@ -531,22 +550,29 @@ class ABC3D_PT_FontCreation(bpy.types.Panel):
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')
box = layout.box()
box.row().label(text="Exporting a fontfile")
box.row().label(text="1. Select export directory:")
box.prop(abc3d_data, 'export_dir')
box.row().label(text="2. More options and export:")
box.row().operator(f"{__name__}.save_font_to_file", text='Export Font To File')
layout.row().operator(f"{__name__}.toggle_abc3d_collection", text='Toggle Collection')
box.row().operator(f"{__name__}.save_font_to_file",
text='Export Font To File')
layout.row().operator(
f"{__name__}.toggle_abc3d_collection", text='Toggle Collection')
box = layout.box()
box.label(text="metrics")
box.row().operator(f"{__name__}.add_default_metrics", text='Add Default Metrics')
box.row().operator(
f"{__name__}.add_default_metrics", text='Add Default Metrics')
box.row().operator(f"{__name__}.remove_metrics", text='Remove Metrics')
box.row().operator(f"{__name__}.align_metrics", text='Align Metrics')
box.row().operator(f"{__name__}.align_metrics_to_active_object", text='Align Metrics to Active Object')
layout.row().operator(f"{__name__}.temporaryhelper", text='Debug Function Do Not Use')
box.row().operator(
f"{__name__}.align_metrics_to_active_object", text='Align Metrics to Active Object')
layout.row().operator(
f"{__name__}.temporaryhelper", text='Debug Function Do Not Use')
class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
bl_label = "Text Properties"
@ -556,7 +582,8 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
bl_region_type = "UI"
def get_active_text_properties(self):
if type(bpy.context.active_object) != type(None):# and bpy.context.object.select_get():
# and bpy.context.object.select_get():
if type(bpy.context.active_object) != type(None):
for t in bpy.context.scene.abc3d_data.available_texts:
if bpy.context.active_object == t.text_object:
return t
@ -592,7 +619,7 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
# )
@classmethod
def poll(self,context):
def poll(self, context):
return type(self.get_active_text_properties(self)) != type(None)
def draw(self, context):
@ -620,6 +647,7 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
layout.column().prop(props, "translation")
layout.column().prop(props, "orientation")
class ABC3D_OT_InstallFont(bpy.types.Operator):
"""Install or load Fontfile from path above.
(Format must be *.glb or *.gltf)"""
@ -659,7 +687,8 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
layout.row().prop(self, "install_in_assets")
if not self.install_in_assets and not self.load_into_memory:
layout.label(text="If the fontfile is not installed,")
layout.label(text="and the font is not loaded in memory completely,")
layout.label(
text="and the font is not loaded in memory completely,")
layout.label(text="the fontfile should not be moved.")
layout.row().prop(self, "load_into_memory")
if self.load_into_memory:
@ -719,6 +748,7 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
return {'FINISHED'}
class ABC3D_OT_OpenAssetDirectory(bpy.types.Operator):
"""Open Asset Directory"""
bl_idname = f"{__name__}.open_asset_directory"
@ -781,6 +811,7 @@ class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
return {'FINISHED'}
class ABC3D_OT_LoadFont(bpy.types.Operator):
"""Load all glyphs from a specific font in memory.\nThis can take a while and slow down Blender."""
bl_idname = f"{__name__}.load_font"
@ -796,6 +827,7 @@ class ABC3D_OT_LoadFont(bpy.types.Operator):
butils.load_font_from_filepath(f)
return {'FINISHED'}
class ABC3D_OT_AddDefaultMetrics(bpy.types.Operator):
"""Add default metrics to selected objects"""
bl_idname = f"{__name__}.add_default_metrics"
@ -807,6 +839,7 @@ class ABC3D_OT_AddDefaultMetrics(bpy.types.Operator):
butils.add_default_metrics_to_objects(objects)
return {'FINISHED'}
class ABC3D_OT_RemoveMetrics(bpy.types.Operator):
"""Remove metrics from selected objects"""
bl_idname = f"{__name__}.remove_metrics"
@ -818,6 +851,7 @@ class ABC3D_OT_RemoveMetrics(bpy.types.Operator):
butils.remove_metrics_from_objects(objects)
return {'FINISHED'}
class ABC3D_OT_AlignMetricsToActiveObject(bpy.types.Operator):
"""Align metrics of selected objects to metrics of active object"""
bl_idname = f"{__name__}.align_metrics_to_active_object"
@ -829,6 +863,7 @@ class ABC3D_OT_AlignMetricsToActiveObject(bpy.types.Operator):
butils.align_metrics_of_objects_to_active_object(objects)
return {'FINISHED'}
class ABC3D_OT_AlignMetrics(bpy.types.Operator):
"""Align metrics of selected objects to each other"""
bl_idname = f"{__name__}.align_metrics"
@ -840,6 +875,7 @@ class ABC3D_OT_AlignMetrics(bpy.types.Operator):
butils.align_metrics_of_objects(objects)
return {'FINISHED'}
class ABC3D_OT_TemporaryHelper(bpy.types.Operator):
"""Temporary Helper ABC3D\nThis could do anything.\nIt's just there to make random functions available for testing."""
bl_idname = f"{__name__}.temporaryhelper"
@ -867,6 +903,7 @@ class ABC3D_OT_TemporaryHelper(bpy.types.Operator):
return {'FINISHED'}
class ABC3D_OT_RemoveText(bpy.types.Operator):
"""Remove Text 3D"""
bl_idname = f"{__name__}.remove_text"
@ -894,17 +931,18 @@ class ABC3D_OT_RemoveText(bpy.types.Operator):
i = abc3d_data.active_text_index
if type(abc3d_data.available_texts[i].text_object) != type(None):
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")
delif(mom,f"{utils.prefix()}_offset")
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")
delif(mom, f"{utils.prefix()}_offset")
if self.remove_objects:
remove_list = []
for g in abc3d_data.available_texts[i].glyphs:
@ -1040,6 +1078,7 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
return {'FINISHED'}
class ABC3D_OT_ToggleABC3DCollection(bpy.types.Operator):
"""Toggle ABC3D Collection"""
bl_idname = f"{__name__}.toggle_abc3d_collection"
@ -1051,7 +1090,8 @@ class ABC3D_OT_ToggleABC3DCollection(bpy.types.Operator):
fontcollection = bpy.data.collections.get("ABC3D")
if fontcollection is None:
self.report({'INFO'}, f"{bl_info['name']}: There is no collection. Did you use or create any glyphs yet?")
self.report(
{'INFO'}, f"{bl_info['name']}: There is no collection. Did you use or create any glyphs yet?")
elif scene.collection.children.find(fontcollection.name) < 0:
scene.collection.children.link(fontcollection)
self.report({'INFO'}, f"{bl_info['name']}: show collection")
@ -1073,27 +1113,32 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
preferences = getPreferences(context)
abc3d_data = context.scene.abc3d_data
if abc3d_data.export_dir == "":
abc3d_data.export_dir = os.path.join(preferences.assets_dir, "fonts")
abc3d_data.export_dir = os.path.join(
preferences.assets_dir, "fonts")
return wm.invoke_props_dialog(self)
def draw(self, context):
abc3d_data = context.scene.abc3d_data
layout = self.layout
layout.label(text="Available Fonts")
layout.template_list("ABC3D_UL_fonts", "", abc3d_data, "available_fonts", abc3d_data, "active_font_index")
layout.template_list("ABC3D_UL_fonts", "", 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
loaded_glyphs = sorted(Font.fonts[font_name].faces[face_name].loaded_glyphs)
loaded_glyphs = sorted(
Font.fonts[font_name].faces[face_name].loaded_glyphs)
n = 16
n_rows = int(len(loaded_glyphs) / n)
box = layout.box()
box.row().label(text=f"Glyphs to be exported:")
subbox = box.box()
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])
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 = subbox.row(); row.scale_y = scale_y
row = subbox.row()
row.scale_y = scale_y
row.label(text=text)
layout.prop(abc3d_data, 'export_dir')
@ -1110,15 +1155,18 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
return {'CANCELLED'}
if abc3d_data.active_font_index < 0:
self.report({'INFO'}, f"{bl_info['name']}: There is no active font")
self.report(
{'INFO'}, f"{bl_info['name']}: There is no active font")
return {'CANCELLED'}
if len(abc3d_data.available_fonts) <= abc3d_data.active_font_index:
self.report({'INFO'}, f"{bl_info['name']}: Active font is not available")
self.report(
{'INFO'}, f"{bl_info['name']}: Active font is not available")
return {'CANCELLED'}
# save state to restore later
was_fontcollection_linked = scene.collection.children.find(fontcollection.name) >= 0
was_fontcollection_linked = scene.collection.children.find(
fontcollection.name) >= 0
was_selection = []
for obj in bpy.context.selected_objects:
was_selection.append(obj)
@ -1130,7 +1178,8 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
selected_font = abc3d_data.available_fonts[abc3d_data.active_font_index]
# print(selected_font.font_name)
self.report({'INFO'}, f"{bl_info['name']}: {selected_font.font_name} {selected_font.face_name}")
self.report(
{'INFO'}, f"{bl_info['name']}: {selected_font.font_name} {selected_font.face_name}")
preferences = getPreferences(context)
print(f"assets folder: {preferences.assets_dir}")
@ -1169,12 +1218,14 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
bpy.ops.export_scene.gltf(
filepath=filepath,
check_existing=False,
export_format='GLB', # GLB or GLTF_SEPARATE (also change filepath)
# GLB or GLTF_SEPARATE (also change filepath)
export_format='GLB',
export_extras=True,
use_selection=True,
use_active_scene=True,
)
bpy.app.timers.register(lambda: bpy.ops.scene.delete(), first_interval=1)
bpy.app.timers.register(
lambda: bpy.ops.scene.delete(), first_interval=1)
# bpy.ops.scene.delete()
# restore()
@ -1229,29 +1280,42 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
row.prop(self, 'autodetect_names')
if self.autodetect_names:
scale_y = 0.5
row = layout.row(); row.scale_y = scale_y
row.label(text="Watch out, follow convention in naming your meshes:")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(
text="Watch out, follow convention in naming your meshes:")
row = layout.row()
row.scale_y = scale_y
row.label(text="'<glyph id>_<font name>_<face name>'")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text=" - glyph id: unicode glyph name or raw glyph")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text=" - font name: font name with underscore")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text=" - face name: face name")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="working examples:")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- 'A_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- 'B_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- 'arrowright_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- '→_NM_Origin_Tender' (equal to above)")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- 'quotesingle_NM_Origin_Tender.001'")
row = layout.row(); row.scale_y = scale_y
row = layout.row()
row.scale_y = scale_y
row.label(text="- 'colon_NM_Origin_Tender_2'")
box = layout.box()
box.enabled = not self.autodetect_names
@ -1264,8 +1328,10 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
character = ""
if Font.known_misspellings[k] in Font.name_to_glyph_d:
character = f" ({Font.name_to_glyph_d[Font.known_misspellings[k]]})"
row = layout.row(); row.scale_y = 0.5
row.label(text=f"{k}{Font.known_misspellings[k]}{character}")
row = layout.row()
row.scale_y = 0.5
row.label(
text=f"{k}{Font.known_misspellings[k]}{character}")
def execute(self, context):
print(f"executing {self.bl_idname}")
@ -1300,7 +1366,8 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
if self.autodetect_names:
ifxsplit = o.name.split('_')
if len(ifxsplit) < 4:
print(f"whoops name could not be autodetected {o.name}")
print(
f"whoops name could not be autodetected {o.name}")
continue
font_name = f"{ifxsplit[1]}_{ifxsplit[2]}"
face_name = ifxsplit[3]
@ -1314,7 +1381,7 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
name = o.name.split('_')[0]
glyph_id = Font.name_to_glyph(name)
if type(glyph_id )!= type(None):
if type(glyph_id) != type(None):
o["glyph"] = glyph_id
o["font_name"] = font_name
o["face_name"] = face_name
@ -1328,7 +1395,7 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
glyph_id,
o)
#TODO: is there a better way to iterate over a CollectionProperty?
# TODO: is there a better way to iterate over a CollectionProperty?
found = False
for f in abc3d_data.available_fonts.values():
if (f.font_name == font_name
@ -1341,11 +1408,14 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
f.face_name = face_name
else:
print(f"import warning: did not understand glyph {name}")
self.report({'INFO'}, f"did not understand glyph {name}")
print(
f"import warning: did not understand glyph {name}")
self.report(
{'INFO'}, f"did not understand glyph {name}")
return {'FINISHED'}
class ABC3D_PT_RightPropertiesPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_label = f"{bl_info['name']}"
@ -1355,10 +1425,12 @@ class ABC3D_PT_RightPropertiesPanel(bpy.types.Panel):
bl_context = "object"
@classmethod
def poll(self,context):
def poll(self, context):
# only show the panel, if it's a textobject or a glyph
is_text = type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object == context.active_object), None)) != type(None)
is_glyph = type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object == context.active_object.parent), None)) != type(None)
is_text = type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object ==
context.active_object), None)) != type(None)
is_glyph = type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object ==
context.active_object.parent), None)) != type(None)
return is_text or is_glyph
def draw(self, context):
@ -1370,6 +1442,7 @@ class ABC3D_PT_RightPropertiesPanel(bpy.types.Panel):
def is_it_text():
return type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object == context.active_object), None)) != type(None)
def is_it_glyph():
return type(next((t for t in context.scene.abc3d_data.available_texts if t.text_object == context.active_object.parent), None)) != type(None)
@ -1401,6 +1474,7 @@ class ABC3D_PT_RightPropertiesPanel(bpy.types.Panel):
if is_glyph:
layout.row().label(text="Glyph Properties:")
class ABC3D_OT_Reporter(bpy.types.Operator):
bl_idname = f"{__name__}.reporter"
bl_label = "Report"
@ -1415,12 +1489,13 @@ class ABC3D_OT_Reporter(bpy.types.Operator):
)
def execute(self, context):
#this is where I send the message
# this is where I send the message
self.report({'INFO'}, 'whatever')
for i in range(0,10):
butils.ShowMessageBox('whatever','INFO','INFO')
for i in range(0, 10):
butils.ShowMessageBox('whatever', 'INFO', 'INFO')
return {'FINISHED'}
classes = (
bimport.ImportGLTF2,
bimport.GetFontFacesInFile,
@ -1454,7 +1529,8 @@ classes = (
ABC3D_OT_CreateFontFromObjects,
ABC3D_PT_RightPropertiesPanel,
ABC3D_OT_Reporter,
)
)
def compare_text_object_with_object(t, o, strict=False):
for k in o.keys():
@ -1462,7 +1538,7 @@ def compare_text_object_with_object(t, o, strict=False):
if o[k] != "textobject":
return False
elif k.startswith(f"{utils.prefix()}_"):
p = k.replace(f"{utils.prefix()}_","")
p = k.replace(f"{utils.prefix()}_", "")
if p in t.keys():
if t[p] != o[k]:
return False
@ -1474,6 +1550,7 @@ def compare_text_object_with_object(t, o, strict=False):
# if
return True
def detect_text():
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
@ -1483,9 +1560,11 @@ def detect_text():
if len(abc3d_data.available_texts) > linked_textobject \
and abc3d_data.available_texts[linked_textobject].text_object == o:
t = abc3d_data.available_texts[linked_textobject]
a = test_availability(o["font_name"], o["face_name"], o["text"])
a = test_availability(
o["font_name"], o["face_name"], o["text"])
butils.transfer_blender_object_to_text_properties(o, t)
def load_used_glyphs():
print("LOAD USED GLYPHS")
scene = bpy.context.scene
@ -1519,16 +1598,19 @@ def load_handler(self, dummy):
butils.run_in_main_thread(bpy.ops.abc3d.load_installed_fonts)
butils.run_in_main_thread(load_used_glyphs)
def load_handler_unload():
if bpy.app.timers.is_registered(butils.execute_queued_functions):
bpy.app.timers.unregister(butils.execute_queued_functions)
@persistent
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)
@persistent
def on_depsgraph_update(scene, depsgraph):
for u in depsgraph.updates:
@ -1538,7 +1620,8 @@ def on_depsgraph_update(scene, depsgraph):
linked_textobject = u.id[f"{utils.prefix()}_linked_textobject"]
if u.is_updated_geometry and len(scene.abc3d_data.available_texts) > linked_textobject and not "prevent_recursion" in u.id:
u.id["prevent_recursion"] = True
butils.set_text_on_curve(scene.abc3d_data.available_texts[linked_textobject])
butils.set_text_on_curve(
scene.abc3d_data.available_texts[linked_textobject])
elif "prevent_recursion" in u.id.keys():
del u.id["prevent_recursion"]
@ -1574,6 +1657,7 @@ def register():
Font.name_to_glyph_d = Font.generate_name_to_glyph_d()
def unregister():
addon_updater_ops.unregister()
@ -1592,6 +1676,6 @@ def unregister():
del bpy.types.Scene.abc3d_data
print(f"UNREGISTER {bl_info['name']}")
if __name__ == '__main__':
register()