text on line
This commit is contained in:
parent
d06bf038b0
commit
7534699fb5
3 changed files with 172 additions and 15 deletions
130
__init__.py
130
__init__.py
|
@ -32,6 +32,7 @@ else:
|
|||
|
||||
import bpy
|
||||
import math
|
||||
import mathutils
|
||||
import io
|
||||
import functools
|
||||
from bpy.types import Panel
|
||||
|
@ -41,6 +42,7 @@ from random import uniform
|
|||
import time
|
||||
import datetime
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
|
@ -50,9 +52,55 @@ class SharedVariables():
|
|||
def __init__(self, **kv):
|
||||
self.__dict__.update(kv)
|
||||
|
||||
def getPreferences(context):
|
||||
preferences = context.preferences
|
||||
return preferences.addons[__name__].preferences
|
||||
|
||||
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):
|
||||
"""Font 3D"""
|
||||
|
@ -84,6 +132,11 @@ class FONT3D_settings(bpy.types.PropertyGroup):
|
|||
default="_NM_",
|
||||
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):
|
||||
|
@ -127,9 +180,13 @@ class FONT3D_PT_panel(bpy.types.Panel):
|
|||
layout.label(text="Available Fonts")
|
||||
layout.template_list("FONT3D_UL_fonts", "", font3d_data, "available_fonts", font3d_data, "active_font_index")
|
||||
layout.label(text='DEBUG')
|
||||
layout.row().prop(font3d, "test_text")
|
||||
layout.row().operator('font3d.testfont', text='Test Font')
|
||||
layout.label(text="font creation")
|
||||
layout.row().prop(font3d, "import_infix")
|
||||
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.label(text='DEBUG END')
|
||||
|
||||
|
@ -145,6 +202,13 @@ class FONT3D_OT_LoadFont(bpy.types.Operator):
|
|||
scene = bpy.context.scene
|
||||
|
||||
# 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 = []
|
||||
for ob in bpy.data.objects:
|
||||
|
@ -180,6 +244,7 @@ class FONT3D_OT_LoadFont(bpy.types.Operator):
|
|||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class FONT3D_OT_TestFont(bpy.types.Operator):
|
||||
"""Test Font 3D"""
|
||||
bl_idname = "font3d.testfont"
|
||||
|
@ -190,14 +255,40 @@ class FONT3D_OT_TestFont(bpy.types.Operator):
|
|||
global shared
|
||||
scene = bpy.context.scene
|
||||
|
||||
|
||||
selected = bpy.context.view_layer.objects.active
|
||||
|
||||
glyph = Font.get_glyph("NM_Origin", "Tender", "A").data
|
||||
ob = bpy.data.objects.new('Duplicate_Linked', glyph)
|
||||
ob.location = selected.location
|
||||
if selected:
|
||||
font_name = "NM_Origin"
|
||||
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)
|
||||
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'}
|
||||
|
||||
|
@ -223,6 +314,31 @@ class FONT3D_OT_ToggleFont3DCollection(bpy.types.Operator):
|
|||
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):
|
||||
"""Create Font from open objects"""
|
||||
bl_idname = "font3d.create_font_from_objects"
|
||||
|
@ -247,6 +363,7 @@ class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
|||
added_font = False
|
||||
|
||||
font3d_data.available_fonts.clear()
|
||||
Font.fonts = {}
|
||||
|
||||
currentObjects = []
|
||||
for o in bpy.data.objects:
|
||||
|
@ -289,7 +406,9 @@ class FONT3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
|||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
FONT3D_addonPreferences,
|
||||
FONT3D_OT_Font3D,
|
||||
FONT3D_available_font,
|
||||
FONT3D_data,
|
||||
|
@ -299,6 +418,7 @@ classes = (
|
|||
FONT3D_OT_TestFont,
|
||||
FONT3D_OT_LoadFont,
|
||||
FONT3D_OT_ToggleFont3DCollection,
|
||||
FONT3D_OT_SaveFontToFile,
|
||||
FONT3D_OT_CreateFontFromObjects,
|
||||
)
|
||||
|
||||
|
@ -309,8 +429,6 @@ def register():
|
|||
bpy.types.Scene.font3d_data = bpy.props.PointerProperty(type=FONT3D_data)
|
||||
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
|
||||
# if load_handler not in bpy.app.handlers.load_post:
|
||||
# bpy.app.handlers.load_post.append(load_handler)
|
||||
|
|
50
butils.py
50
butils.py
|
@ -23,10 +23,46 @@ def move_in_fontcollection(obj, fontcollection, scene):
|
|||
scene.collection.objects.unlink(obj)
|
||||
if fontcollection.objects.find(obj.name) < 0:
|
||||
fontcollection.objects.link(obj)
|
||||
if fontcollection.objects.find("glyphs") < 0:
|
||||
empty = bpy.data.objects.new("glyphs", None)
|
||||
empty.empty_display_type = 'PLAIN_AXES'
|
||||
fontcollection.objects.link(empty)
|
||||
glyphs = fontcollection.objects.get("glyphs")
|
||||
if obj.parent != glyphs:
|
||||
obj.parent = glyphs
|
||||
# TODO: move in glyphs
|
||||
# if fontcollection.objects.find("glyphs") < 0:
|
||||
# empty = bpy.data.objects.new("glyphs", None)
|
||||
# empty.empty_display_type = 'PLAIN_AXES'
|
||||
# fontcollection.objects.link(empty)
|
||||
# glyphs = fontcollection.objects.get("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)
|
||||
|
|
|
@ -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]
|
||||
|
||||
def get_loaded_fonts():
|
||||
return fonts.keys()
|
||||
|
||||
# holds all fonts
|
||||
fonts = {}
|
||||
|
|
Loading…
Reference in a new issue