【Blender插件】Blender 中文输入文字
目前不支持多行,
转竖版再转回来,位置会错。
代码
'''
Copyright (C) 2019 Red Halo Studio(发霉的红地蛋)
Created by Red Halo Studio(发霉的红地蛋)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
bl_info = {
"name": "Text Input",
"author": "Red Halo Studio",
"version": (0, 2),
"blender": (2, 80, 0),
"location": "Properties > Font > Text Value",
"description": "解决Window下无法输入中文的问题",
"wiki_url": "",
"tracker_url": "",
"category": "RedHaloTools"
}
from typing import Collection
import bpy
from bpy.types import Operator, UIList, PropertyGroup, Panel, Scene
from bpy.props import StringProperty, IntProperty, CollectionProperty, EnumProperty, PointerProperty, BoolProperty
import os
import platform
plat = platform.system().lower()
if plat == "windows":
FontFolder = os.getenv("SystemRoot") + "\\Fonts"
elif plat == "linux":
FontFolder = "/usr/share/fonts"
else:
FontFolder = "/System/Library/Fonts"
filterFont = ["AIGDT___.TTF", ]
def getFonts():
# filters = [".fon"] # 过滤的fbx文件
enum_fonts_list = []
list = os.listdir(FontFolder)
for i in list:
count = 0
path = os.path.join(FontFolder,i)
if os.path.isfile(path):
fileExtension = os.path.splitext(path)[-1].lower()
if fileExtension != ".fon":
id = str(i)
name = str(i[:-4])
description = str(i)
enum_fonts_list.append((id, name, description))
count += 1
return enum_fonts_list
fonts = getFonts()
class REDHALO_OT_SetFont(Operator):
""" Set Font """
bl_idname = "redhalo.select_font"
bl_label = "Select Font"
bl_property = "font_list"
font_list : EnumProperty(
items = fonts
)
def execute(self, context):
fontName = self.font_list
fontPath = os.path.join(FontFolder, fontName)
font = bpy.data.fonts.load(filepath=fontPath)
allFonts = bpy.data.fonts
for f in range(len(allFonts)):
if allFonts[f].name == font.name:
bpy.context.active_object.data.font = allFonts[f]
else:
bpy.context.active_object.data.font = font
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
wm.invoke_search_popup(self)
return {'FINISHED'}
class Tools_OT_insertNewline(Operator):
bl_idname = "redhalo.insert_newline"
bl_label = "插入换行符"
bl_description = "Insert Newline Symbol\n插入换行符"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
bpy.context.active_object.data.body += "\n"
return {'FINISHED'}
class Tools_OT_setFont(Operator):
bl_idname = "redhalo.set_font"
bl_label = "修改字体"
bl_description = "设置为思源黑体"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
addonPath = os.path.dirname(__file__)
fontName = "SourceHanSansCN-Normal.otf"
fontPath = os.path.join(addonPath,fontName)
font = bpy.data.fonts.load(filepath=fontPath)
allFonts = bpy.data.fonts
for f in range(len(allFonts)):
if allFonts[f].name == font.name:
bpy.context.active_object.data.font = allFonts[f]
else:
bpy.context.active_object.data.font = font
return {'FINISHED'}
class Tools_OT_VerticalText(Operator):
bl_idname = "redhalo.set_vertical"
bl_label = "改为竖向文字"
bl_description = "改为竖向文字"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
ob = context.active_object
txt = ob.data.body[:]
textArray = ob.data.body.split("\n")
maxLength = 0
for i in textArray:
if len(i) > maxLength:
maxLength = len(i)
for i, v in enumerate(textArray):
diff = maxLength - len(v)
textArray[i] += ("\x20" * diff) #中文空格
verticalArray = zip(*reversed(textArray))
verticalStr = ""
for i, val in enumerate(verticalArray):
_t = ""
for j in val:
_t += j
verticalStr += _t + "\n"
verticalStr = verticalStr[:-1]
ob.data.body = verticalStr
ob.data.align_x = "RIGHT"
return {'FINISHED'}
class REDHALO_UL_TextMain(UIList):
# The draw_item function is called for each item of the collection that is visible in the list.
# data is the RNA object containing the collection,
# item is the current drawn item of the collection,
# icon is the "computed" icon for the item (as an integer, because some objects like materials or textures
# have custom icons ID, which are not available as enum items).
# active_data is the RNA object containing the active property for the collection (i.e. integer pointing to the
# active item of the collection).
# active_propname is the name of the active property (use 'getattr(active_data, active_propname)').
# index is index of the current item in the collection.
# flt_flag is the result of the filtering process for this item.
# Note: as index and flt_flag are optional arguments, you do not have to use/declare them here if you don't
# need them.
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
custom_icon = "OBJECT_DATAMODE"
layout.label(text='', icon = custom_icon)
sp = layout.split(factor = 0.2)
sp.label(text = "Index: %d" % (index))
sp.prop(item, "name", text="")
class REDHALO_OT_InsertLine(Operator):
""" Insert New Line """
bl_idname = "redhalo.insert_new_line"
bl_label = "Insert new line"
def execute(self, context):
context.scene.my_list.add()
return {'FINISH'}
class REDHALO_OT_DeleteLine(Operator):
''' Delete the selected item from the list'''
bl_idname = "redhalo.delete_item"
bl_label = "Delete seleced item"
@classmethod
def poll(cls, context):
return context.scene.my_list
def excute(self, context):
my_list = context.scene.my_list
index = context.scene.list_index
my_list.remove(index)
context.scene.list_index = min(max(0, index-1), len(my_list)-1)
return {'FINISH'}
class RD_PT_TextValue(Panel):
bl_label = "Text Value"
bl_idname = "OBJECT_PT_hello"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@classmethod
def poll(cls, context):
active = bpy.context.active_object
if active is not None:
active_type=active.type
else:
active_type=""
return active_type=='FONT'
def draw(self, context):
layout = self.layout
scene = context.scene
fontname = context.active_object.data.font.name
obj = context.object
row = layout.row()
row.prop(obj.data, "body", text="", icon="OUTLINER_OB_FONT",expand =True )
row = layout.row()
row.operator("redhalo.insert_newline", icon = "CHECKMARK")
# row.operator("redhalo.set_font", icon = "FILE_FONT")
# row = layout.row()
row.operator("redhalo.set_vertical", icon = "DRIVER_ROTATIONAL_DIFFERENCE")
#Font List
row = layout.row()
# row.template_list("REDHALO_UL_TextMain", "LIST", scene, "my_list", scene, "list_index")
row.operator("redhalo.select_font", text = "当前:%s ,点击选择字体" % fontname)
classes = (
REDHALO_OT_SetFont,
Tools_OT_insertNewline,
Tools_OT_setFont,
Tools_OT_VerticalText,
REDHALO_UL_TextMain,
RD_PT_TextValue
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
if __name__ == "__main__":
register()
说明:如果有精彩文章或者技巧,欢迎投稿