180 lines
4.8 KiB
Python
180 lines
4.8 KiB
Python
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
"""
|
|
A 3D font helper
|
|
"""
|
|
|
|
bl_info = {
|
|
"name": "Font3D",
|
|
"author": "Jakob Schlötter, Studio Pointer*",
|
|
"version": (0, 0, 1),
|
|
"blender": (4, 1, 0),
|
|
"location": "wherever it may be",
|
|
"description": "Does Font3D stuff",
|
|
"category": "Typography",
|
|
}
|
|
|
|
import bpy
|
|
import math
|
|
import io
|
|
import functools
|
|
from bpy.types import Panel
|
|
from bpy.app.handlers import persistent
|
|
from random import uniform
|
|
|
|
import time
|
|
import datetime
|
|
|
|
def get_timestamp():
|
|
return datetime.datetime.fromtimestamp(time.time()).strftime('%Y.%m.%d-%H:%M:%S')
|
|
|
|
class SharedVariables():
|
|
fonts: dict = {}
|
|
def __init__(self, **kv):
|
|
self.__dict__.update(kv)
|
|
|
|
shared = SharedVariables()
|
|
|
|
def mapRange(in_value, in_min, in_max, out_min, out_max, clamp=False):
|
|
output = out_min + ((out_max - out_min) / (in_max - in_min)) * (in_value - in_min)
|
|
if clamp:
|
|
if out_min < out_max:
|
|
return min(out_max, max(out_min, output))
|
|
else:
|
|
return max(out_max, min(out_min, output))
|
|
else:
|
|
return output
|
|
|
|
class FONT3D_OT_Font3D(bpy.types.Operator):
|
|
"""Font 3D"""
|
|
bl_idname = "font3d.font3d"
|
|
bl_label = "Font 3D"
|
|
bl_options = {'REGISTER', 'UNDO'}
|
|
|
|
def execute(self, context):
|
|
global shared
|
|
|
|
print("Font3d execute()")
|
|
|
|
scene = bpy.context.scene
|
|
|
|
file_dir = scene.font3d.file_dir
|
|
print(f"file_dir: {file_dir}")
|
|
|
|
return {'FINISHED'}
|
|
|
|
|
|
class FONT3D_settings(bpy.types.PropertyGroup):
|
|
font_path: bpy.props.StringProperty(name="Font path",
|
|
description="Where is the font",
|
|
default="",
|
|
maxlen=1024,
|
|
subtype="FILE_PATH")
|
|
|
|
class FONT3D_PT_panel(bpy.types.Panel):
|
|
bl_label = "Panel for Font3D"
|
|
bl_category = "Font3D"
|
|
bl_space_type = "VIEW_3D"
|
|
bl_region_type = "UI"
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
wm = context.window_manager
|
|
scene = context.scene
|
|
|
|
font3d = scene.font3d
|
|
layout.label(text="Load FontFile:")
|
|
layout.row().prop(font3d, "font_path")
|
|
layout.row().operator('font3d.loadfont', text='Load Font')
|
|
layout.label(text='DEBUG')
|
|
layout.row().operator('font3d.testfont', text='Test Font')
|
|
|
|
class FONT3D_OT_LoadFont(bpy.types.Operator):
|
|
"""Load Font 3D"""
|
|
bl_idname = "font3d.loadfont"
|
|
bl_label = "Load Font"
|
|
bl_options = {'REGISTER', 'UNDO'}
|
|
|
|
def execute(self, context):
|
|
global shared
|
|
scene = bpy.context.scene
|
|
|
|
print(f"loading da font at path {scene.font3d.font_path}")
|
|
|
|
currentObjects = []
|
|
for ob in bpy.data.objects:
|
|
currentObjects.append(ob.name)
|
|
bpy.ops.import_scene.gltf(filepath=scene.font3d.font_path)
|
|
|
|
newObjects = []
|
|
|
|
fontcollection = bpy.data.collections.new("Font3D")
|
|
scene.collection.children.link(fontcollection)
|
|
|
|
font = {
|
|
"name": "",
|
|
"glyphs": []
|
|
}
|
|
|
|
for o in bpy.data.objects:
|
|
if o.name not in currentObjects:
|
|
if (o.parent == None):
|
|
print(f"found root node --> {o.name}")
|
|
font['name'] = o.name
|
|
elif o.parent.name.startswith("glyphs"):
|
|
print(f"loading glyph --> {o.name}")
|
|
font['glyphs'].append(o)
|
|
newObjects.append(o.name)
|
|
scene.collection.objects.unlink(o)
|
|
fontcollection.objects.link(o)
|
|
|
|
try:
|
|
shared.fonts
|
|
except:
|
|
shared.fonts = {}
|
|
shared.fonts[font['name']] = font
|
|
|
|
return {'FINISHED'}
|
|
|
|
class FONT3D_OT_TestFont(bpy.types.Operator):
|
|
"""Test Font 3D"""
|
|
bl_idname = "font3d.testfont"
|
|
bl_label = "Test Font"
|
|
bl_options = {'REGISTER', 'UNDO'}
|
|
|
|
def execute(self, context):
|
|
global shared
|
|
scene = bpy.context.scene
|
|
|
|
print(shared.fonts)
|
|
|
|
return {'FINISHED'}
|
|
|
|
classes = (
|
|
FONT3D_OT_Font3D,
|
|
FONT3D_settings,
|
|
FONT3D_PT_panel,
|
|
FONT3D_OT_TestFont,
|
|
FONT3D_OT_LoadFont
|
|
)
|
|
|
|
def register():
|
|
for cls in classes:
|
|
bpy.utils.register_class(cls)
|
|
bpy.types.Scene.font3d = bpy.props.PointerProperty(type=FONT3D_settings)
|
|
# 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)
|
|
|
|
def unregister():
|
|
# would love to properly auto start this, but IT DOES NOT WORK
|
|
# if load_handler in bpy.app.handlers.load_post:
|
|
# bpy.app.handlers.load_post.remove(load_handler)
|
|
for cls in classes:
|
|
bpy.utils.unregister_class(cls)
|
|
|
|
del bpy.types.Scene.font3d
|
|
|
|
if __name__ == '__main__':
|
|
register()
|
|
|