text on line

This commit is contained in:
themancalledjakob 2024-05-28 14:11:32 +02:00
parent d06bf038b0
commit 7534699fb5
3 changed files with 172 additions and 15 deletions

View file

@ -32,6 +32,7 @@ else:
import bpy import bpy
import math import math
import mathutils
import io import io
import functools import functools
from bpy.types import Panel from bpy.types import Panel
@ -41,6 +42,7 @@ from random import uniform
import time import time
import datetime import datetime
import os
import re import re
@ -50,9 +52,55 @@ class SharedVariables():
def __init__(self, **kv): def __init__(self, **kv):
self.__dict__.update(kv) self.__dict__.update(kv)
def getPreferences(context):
preferences = context.preferences
return preferences.addons[__name__].preferences
shared = SharedVariables() shared = SharedVariables()
class FONT3D_addonPreferences(bpy.types.AddonPreferences):
"""Font3D Addon Preferences
These are the preferences at Edit/Preferences/Add-ons"""
bl_idname = __name__
def get_default_assets_dir():
return bpy.utils.user_resource(
'DATAFILES',
path=f"{__name__}",
create=True)
def on_change_assets_dir(self, context):
if not os.path.isdir(self.assets_dir):
butils.ShowMessageBox(
title=f"{__name__} Warning",
icon="ERROR",
message=("Chosen directory does not exist.",
"Please, reset to default, create it or chose another one."))
elif not os.access(self.assets_dir, os.W_OK):
butils.ShowMessageBox(
title=f"{__name__} Warning",
icon="ERROR",
message=("Chosen directory is not writable.",
"Please reset to default or chose another one."))
else:
shared.paths["assets"] = self.assets_dir
print(f"{__name__}: change assets_dir to {self.assets_dir}")
assets_dir: bpy.props.StringProperty(
name="Assets Folder",
subtype='DIR_PATH',
default=get_default_assets_dir(),
update=on_change_assets_dir,
)
def draw(self, context):
layout = self.layout
layout.label(text="Directory for storage of fonts and other assets:")
layout.prop(self, "assets_dir")
class FONT3D_OT_Font3D(bpy.types.Operator): class FONT3D_OT_Font3D(bpy.types.Operator):
"""Font 3D""" """Font 3D"""
@ -84,6 +132,11 @@ class FONT3D_settings(bpy.types.PropertyGroup):
default="_NM_", default="_NM_",
maxlen=1024, maxlen=1024,
) )
test_text: bpy.props.StringProperty(name="Test Text",
description="the text to test with",
default="Hello",
maxlen=1024,
)
class FONT3D_available_font(bpy.types.PropertyGroup): class FONT3D_available_font(bpy.types.PropertyGroup):
@ -127,9 +180,13 @@ class FONT3D_PT_panel(bpy.types.Panel):
layout.label(text="Available Fonts") layout.label(text="Available Fonts")
layout.template_list("FONT3D_UL_fonts", "", font3d_data, "available_fonts", font3d_data, "active_font_index") layout.template_list("FONT3D_UL_fonts", "", font3d_data, "available_fonts", font3d_data, "active_font_index")
layout.label(text='DEBUG') layout.label(text='DEBUG')
layout.row().prop(font3d, "test_text")
layout.row().operator('font3d.testfont', text='Test Font') layout.row().operator('font3d.testfont', text='Test Font')
layout.label(text="font creation")
layout.row().prop(font3d, "import_infix") layout.row().prop(font3d, "import_infix")
layout.row().operator('font3d.create_font_from_objects', text='Create Font') layout.row().operator('font3d.create_font_from_objects', text='Create Font')
layout.row().separator()
layout.row().operator('font3d.save_font_to_file', text='Save Font To File')
layout.row().operator('font3d.toggle_font3d_collection', text='Toggle Collection') layout.row().operator('font3d.toggle_font3d_collection', text='Toggle Collection')
layout.label(text='DEBUG END') layout.label(text='DEBUG END')
@ -145,6 +202,13 @@ class FONT3D_OT_LoadFont(bpy.types.Operator):
scene = bpy.context.scene scene = bpy.context.scene
# print(f"loading da font at path {scene.font3d.font_path}") # print(f"loading da font at path {scene.font3d.font_path}")
if not os.path.exists(scene.font3d.font_path):
butils.ShowMessageBox(
title=f"{__name__} Warning",
icon="ERROR",
message=f"We believe the font path ({scene.font3d.font_path}) does not exist.",
)
return {'CANCELLED'}
currentObjects = [] currentObjects = []
for ob in bpy.data.objects: for ob in bpy.data.objects:
@ -180,6 +244,7 @@ class FONT3D_OT_LoadFont(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
class FONT3D_OT_TestFont(bpy.types.Operator): class FONT3D_OT_TestFont(bpy.types.Operator):
"""Test Font 3D""" """Test Font 3D"""
bl_idname = "font3d.testfont" bl_idname = "font3d.testfont"
@ -190,14 +255,40 @@ class FONT3D_OT_TestFont(bpy.types.Operator):
global shared global shared
scene = bpy.context.scene scene = bpy.context.scene
selected = bpy.context.view_layer.objects.active selected = bpy.context.view_layer.objects.active
glyph = Font.get_glyph("NM_Origin", "Tender", "A").data if selected:
ob = bpy.data.objects.new('Duplicate_Linked', glyph) font_name = "NM_Origin"
ob.location = selected.location font_face = "Tender"
offset = mathutils.Vector((0.0, 0.0, 0.0))
advance = 0
for i, c in enumerate(scene.font3d.test_text):
glyph_id = c
glyph = Font.get_glyph(font_name, font_face, glyph_id)
if glyph == None:
self.report({'ERROR'}, f"Glyph not found for {font_name} {font_face} {glyph_id}")
continue
elif glyph.type == "CURVE":
print("is curve")
glyph_advance = (-1 * glyph.bound_box[0][0] + glyph.bound_box[4][0]) * 0.01
offset.x = advance
ob = bpy.data.objects.new(f"{glyph_id}", glyph.data)
ob.location = selected.location + offset
ob.scale = (0.01, 0.01, 0.01) ob.scale = (0.01, 0.01, 0.01)
selected.users_collection[0].objects.link(ob) selected.users_collection[0].objects.link(ob)
ob.parent = selected
advance = advance + glyph_advance
else:
butils.ShowMessageBox(
title="No object selected",
message=(
"Please select an object.",
"It will be used to put the type on.",
"You little piece of shit :)"),
icon='GHOST_ENABLED')
return {'FINISHED'} return {'FINISHED'}
@ -223,6 +314,31 @@ class FONT3D_OT_ToggleFont3DCollection(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
class FONT3D_OT_SaveFontToFile(bpy.types.Operator):
"""Save font to file"""
bl_idname = f"{__name__}.save_font_to_file"
bl_label = "Save Font"
bl_options = {'REGISTER', 'UNDO'}
file_path = "whoopwhoop"
def execute(self, context):
global shared
scene = bpy.context.scene
font3d_data = scene.font3d_data
font3d = scene.font3d
selected_font = font3d_data.available_fonts[font3d_data.active_font_index]
print(selected_font.font_name)
if selected_font == "":
butils.ShowMessageBox("Warning", 'ERROR', "no font selected")
return {'CANCELLED'}
return {'FINISHED'}
class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator): class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator):
"""Create Font from open objects""" """Create Font from open objects"""
bl_idname = "font3d.create_font_from_objects" bl_idname = "font3d.create_font_from_objects"
@ -247,6 +363,7 @@ class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator):
added_font = False added_font = False
font3d_data.available_fonts.clear() font3d_data.available_fonts.clear()
Font.fonts = {}
currentObjects = [] currentObjects = []
for o in bpy.data.objects: for o in bpy.data.objects:
@ -289,7 +406,9 @@ class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
classes = ( classes = (
FONT3D_addonPreferences,
FONT3D_OT_Font3D, FONT3D_OT_Font3D,
FONT3D_available_font, FONT3D_available_font,
FONT3D_data, FONT3D_data,
@ -299,6 +418,7 @@ classes = (
FONT3D_OT_TestFont, FONT3D_OT_TestFont,
FONT3D_OT_LoadFont, FONT3D_OT_LoadFont,
FONT3D_OT_ToggleFont3DCollection, FONT3D_OT_ToggleFont3DCollection,
FONT3D_OT_SaveFontToFile,
FONT3D_OT_CreateFontFromObjects, FONT3D_OT_CreateFontFromObjects,
) )
@ -309,8 +429,6 @@ def register():
bpy.types.Scene.font3d_data = bpy.props.PointerProperty(type=FONT3D_data) bpy.types.Scene.font3d_data = bpy.props.PointerProperty(type=FONT3D_data)
print(f"REGISTER {bl_info['name']}") print(f"REGISTER {bl_info['name']}")
print(utils.get_timestamp())
print(shared.fonts)
# would love to properly auto start this, but IT DOES NOT WORK # would love to properly auto start this, but IT DOES NOT WORK
# if load_handler not in bpy.app.handlers.load_post: # if load_handler not in bpy.app.handlers.load_post:
# bpy.app.handlers.load_post.append(load_handler) # bpy.app.handlers.load_post.append(load_handler)

View file

@ -23,10 +23,46 @@ def move_in_fontcollection(obj, fontcollection, scene):
scene.collection.objects.unlink(obj) scene.collection.objects.unlink(obj)
if fontcollection.objects.find(obj.name) < 0: if fontcollection.objects.find(obj.name) < 0:
fontcollection.objects.link(obj) fontcollection.objects.link(obj)
if fontcollection.objects.find("glyphs") < 0: # TODO: move in glyphs
empty = bpy.data.objects.new("glyphs", None) # if fontcollection.objects.find("glyphs") < 0:
empty.empty_display_type = 'PLAIN_AXES' # empty = bpy.data.objects.new("glyphs", None)
fontcollection.objects.link(empty) # empty.empty_display_type = 'PLAIN_AXES'
glyphs = fontcollection.objects.get("glyphs") # fontcollection.objects.link(empty)
if obj.parent != glyphs: # glyphs = fontcollection.objects.get("glyphs")
obj.parent = glyphs # if obj.parent != glyphs:
# obj.parent = glyphs
def ShowMessageBox(title = "Message Box", icon = 'INFO', message=""):
"""Show a simple message box
taken from `Link here <https://blender.stackexchange.com/questions/169844/multi-line-text-box-with-popup-menu>`_
:param title: The title shown in the message top bar
:type title: str
:param icon: The icon to be shown in the message top bar
:type icon: str
:param message: lines of text to display, a.k.a. the message
:type message: str or (str, str, ..)
TIP: Check `Link blender icons <https://docs.blender.org/api/current/bpy_types_enum_items/icon_items.html>`_ for icons you can use
TIP: Or even better, check `Link this addons <https://docs.blender.org/manual/en/latest/addons/development/icon_viewer.html>`_ to also see the icons.
usage:
.. code-block:: python
myLines=("line 1","line 2","line 3")
butils.ShowMessageBox(message=myLines)
or:
.. code-block:: python
butils.ShowMessageBox(title="",message=("AAAAAH","NOOOOO"),icon=)
"""
myLines=message
def draw(self, context):
if isinstance(myLines, str):
self.layout.label(text=myLines)
elif hasattr(myLines, "__iter__"):
for n in myLines:
self.layout.label(text=n)
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)

View file

@ -114,5 +114,8 @@ def get_glyph(font_name, face_name, glyph_id):
return fonts[font_name].faces[face_name].glyphs.get(glyph_id)[0] return fonts[font_name].faces[face_name].glyphs.get(glyph_id)[0]
def get_loaded_fonts():
return fonts.keys()
# holds all fonts # holds all fonts
fonts = {} fonts = {}