BPYで任意のフォントを表示させてみる

BPYでフォントを扱うには

任意のフォントで文字を表示させたい、そういう場合があるでしょう。

また、フォントによっては直接入力出来ない文字もあります。今回はそんなフォントをBlender3Dビュー上に表示させるのにBPY(Blender Python)の力を借ります。

1.フォントを入手する

まずはフォントを入手します。Blenderで扱えるのはTruetype形式のフォントです。

OSでそれらのフォントが表示出来たとしてもBlenderで表示出来るとは限りません。なぜなら、OSに搭載されたフォントライブラリを使用していないためです。

なお、入手したフォントを使う場合には、そのフォントの使用条件等を良く確認しておきましょう。

たとえば、「フォントを使用した画像は配布を許可するが、グリフそのものを再現できる形での配布は認めない」という条件の場合、フォントをCurveまたはMeshに変換したものを保存した.blendファイルは配布できません。

2.表示させたい文字、キャラクタコードを確認する

キーボードからの入力が出来ない文字の場合、外部プログラムからBlenderのテキストエディタを経由(コピーアンドペーストを使って)して、テキストオブジェクトを新規作成する、ということを行う場合があります。

2.70時点では、「テキストエディタを経由して日本語を含むテキストのテキストオブジェクトを作成可能」「Windows,Macで日本語を扱いたい場合には外部プログラムとして、編集用のテキストエディタを別途用意」というのが現状の模様(5/18確認)。

どうしても入力不可な文字は、unicodeでどのコードに割り当てられているかを確認しておきましょう。

Pythonではユニコードのキャラクタを表現する場合、"\u0000"の形式を取ります。特殊なフォントを使う場合で普通のフォントで表示出来ないものはこちらの形式で。

なお、Blenderの扱う文字コードはUTF-8(BOM無し)。ファイルにする場合には気を付けておきましょう。

3.BPYからテキストオブジェクトを作成する

Blenderにテキストオブジェクトを追加する基本的なコードは以下の通り。オブジェクトを作成して、(作成したオブジェクトをコンテキスト経由で取得して)文字列を当てはめる、というもの。

bpy.ops.object.text_add()

ob=bpy.context.object

ob.data.body = "Hogehoge"

キャラクタコードで指定する場合には、上記2.で得たものを使います。たとえば"あ”を表示させたい場合には"\u3042"を指定します。(「あ」くらいだったらそのままひらがなを入れとけばいいのですが、あくまでサンプルということで。)

bpy.ops.object.text_add()

ob=bpy.context.object

ob.data.body = "\u3042"

4.フォントをロードし、テキストオブジェクトに割り当てる

テキストオブジェクトは追加されましたが、使用するフォントが目的のものではないため、テキストが表示されていないかもしれません。

フォントをロードし、テキストに割り当てます。ロードされたフォントは識別子(フォント内のものを使っている?)で呼び出してオブジェクトに関連付けます。

もちろん、フォントファイルはあらかじめ用意しておきます。

bpy.data.fonts.load(r"C:\usr\fonts\fontawesome-webfont.ttf")

ob.data.font=bpy.data.fonts.get('FontAwesome')

例:Font Awesome の一覧を表示させる

Webフォントとして提供されているFont Awesomeは0xF000 から始まるとかいう感じだったので、一覧を作ってみました。

ソースコード

# Show FontAwesome on blender

#

# [How to Use]

# 1. download fontawesome font and extract, copy .ttf to C:\usr\fonts

# 2. open blender , load or paste this script to text editor, run this script (hit Alt+P)

# [Notice]

# Run this script once on blender,do not twice.

#

import bpy

ft = bpy.data.fonts.get('FontAwesome')

if ft == None:

bpy.data.fonts.load(r"C:\usr\fonts\fontawesome-webfont.ttf") #fontfile path

fa41code = {

"glass":"\uf000",

"music":"\uf001",

"search":"\uf002",

"envelope-o":"\uf003",

"heart":"\uf004",

"star":"\uf005",

"star-o":"\uf006",

"user":"\uf007",

"film":"\uf008",

"th-large":"\uf009",

"th":"\uf00a",

"th-list":"\uf00b",

"check":"\uf00c",

"times":"\uf00d",

"search-plus":"\uf00e",

"search-minus":"\uf010",

"power-off":"\uf011",

"signal":"\uf012",

"gear":"\uf013", # alias:cog

"trash-o":"\uf014",

"home":"\uf015",

"file-o":"\uf016",

"clock-o":"\uf017",

"road":"\uf018",

"download":"\uf019",

"arrow-circle-o-down":"\uf01a",

"arrow-circle-o-up":"\uf01b",

"inbox":"\uf01c",

"play-circle-o":"\uf01d",

"rotate":"\uf01e", # alias:repeat

"refresh":"\uf021",

"list-alt":"\uf022",

"lock":"\uf023",

"flag":"\uf024",

"headphones":"\uf025",

"volume-off":"\uf026",

"volume-down":"\uf027",

"volume-up":"\uf028",

"qrcode":"\uf029",

"barcode":"\uf02a",

"tag":"\uf02b",

"tags":"\uf02c",

"book":"\uf02d",

"bookmark":"\uf02e",

"print":"\uf02f",

"camera":"\uf030",

"font":"\uf031",

"bold":"\uf032",

"italic":"\uf033",

"text-height":"\uf034",

"text-width":"\uf035",

"align-left":"\uf036",

"align-center":"\uf037",

"align-right":"\uf038",

"align-justify":"\uf039",

"list":"\uf03a",

"dedent":"\uf03b", # alias:outdent

"indent":"\uf03c",

"video-camera":"\uf03d",

"photo":"\uf03e", # alias:image,picture-o

"pencil":"\uf040",

"map-marker":"\uf041",

"adjust":"\uf042",

"tint":"\uf043",

"edit":"\uf044", # alias:pencil-square-o

"share-square-o":"\uf045",

"check-square-o":"\uf046",

"arrows":"\uf047",

"step-backward":"\uf048",

"fast-backward":"\uf049",

"backward":"\uf04a",

"play":"\uf04b",

"pause":"\uf04c",

"stop":"\uf04d",

"forward":"\uf04e",

"fast-forward":"\uf050",

"step-forward":"\uf051",

"eject":"\uf052",

"chevron-left":"\uf053",

"chevron-right":"\uf054",

"plus-circle":"\uf055",

"minus-circle":"\uf056",

"times-circle":"\uf057",

"check-circle":"\uf058",

"question-circle":"\uf059",

"info-circle":"\uf05a",

"crosshairs":"\uf05b",

"times-circle-o":"\uf05c",

"check-circle-o":"\uf05d",

"ban":"\uf05e",

"arrow-left":"\uf060",

"arrow-right":"\uf061",

"arrow-up":"\uf062",

"arrow-down":"\uf063",

"mail-forward":"\uf064", # alias:share

"expand":"\uf065",

"compress":"\uf066",

"plus":"\uf067",

"minus":"\uf068",

"asterisk":"\uf069",

"exclamation-circle":"\uf06a",

"gift":"\uf06b",

"leaf":"\uf06c",

"fire":"\uf06d",

"eye":"\uf06e",

"eye-slash":"\uf070",

"warning":"\uf071", # alias:exclamation-triangle

"plane":"\uf072",

"calendar":"\uf073",

"random":"\uf074",

"comment":"\uf075",

"magnet":"\uf076",

"chevron-up":"\uf077",

"chevron-down":"\uf078",

"retweet":"\uf079",

"shopping-cart":"\uf07a",

"folder":"\uf07b",

"folder-open":"\uf07c",

"arrows-v":"\uf07d",

"arrows-h":"\uf07e",

"bar-chart-o":"\uf080",

"twitter-square":"\uf081",

"facebook-square":"\uf082",

"camera-retro":"\uf083",

"key":"\uf084",

"gears":"\uf085", # alias:cogs

"comments":"\uf086",

"thumbs-o-up":"\uf087",

"thumbs-o-down":"\uf088",

"star-half":"\uf089",

"heart-o":"\uf08a",

"sign-out":"\uf08b",

"linkedin-square":"\uf08c",

"thumb-tack":"\uf08d",

"external-link":"\uf08e",

"sign-in":"\uf090",

"trophy":"\uf091",

"github-square":"\uf092",

"upload":"\uf093",

"lemon-o":"\uf094",

"phone":"\uf095",

"square-o":"\uf096",

"bookmark-o":"\uf097",

"phone-square":"\uf098",

"twitter":"\uf099",

"facebook":"\uf09a",

"github":"\uf09b",

"unlock":"\uf09c",

"credit-card":"\uf09d",

"rss":"\uf09e",

"hdd-o":"\uf0a0",

"bullhorn":"\uf0a1",

"bell":"\uf0f3",

"certificate":"\uf0a3",

"hand-o-right":"\uf0a4",

"hand-o-left":"\uf0a5",

"hand-o-up":"\uf0a6",

"hand-o-down":"\uf0a7",

"arrow-circle-left":"\uf0a8",

"arrow-circle-right":"\uf0a9",

"arrow-circle-up":"\uf0aa",

"arrow-circle-down":"\uf0ab",

"globe":"\uf0ac",

"wrench":"\uf0ad",

"tasks":"\uf0ae",

"filter":"\uf0b0",

"briefcase":"\uf0b1",

"arrows-alt":"\uf0b2",

"group":"\uf0c0", # alias:users

"chain":"\uf0c1", # alias:link

"cloud":"\uf0c2",

"flask":"\uf0c3",

"cut":"\uf0c4", # alias:scissors

"copy":"\uf0c5", # alias:files-o

"paperclip":"\uf0c6",

"save":"\uf0c7", # alias:floppy-o

"square":"\uf0c8",

"navicon":"\uf0c9", # alias:reorder,bars

"list-ul":"\uf0ca",

"list-ol":"\uf0cb",

"strikethrough":"\uf0cc",

"underline":"\uf0cd",

"table":"\uf0ce",

"magic":"\uf0d0",

"truck":"\uf0d1",

"pinterest":"\uf0d2",

"pinterest-square":"\uf0d3",

"google-plus-square":"\uf0d4",

"google-plus":"\uf0d5",

"money":"\uf0d6",

"caret-down":"\uf0d7",

"caret-up":"\uf0d8",

"caret-left":"\uf0d9",

"caret-right":"\uf0da",

"columns":"\uf0db",

"unsorted":"\uf0dc", # alias:sort

"sort-down":"\uf0dd", # alias:sort-desc

"sort-up":"\uf0de", # alias:sort-asc

"envelope":"\uf0e0",

"linkedin":"\uf0e1",

"rotate":"\uf0e2", # alias:sort-undo

"legal":"\uf0e3", # alias:gavel

"dashboard":"\uf0e4", # alias:tachometer

"comment-o":"\uf0e5",

"comments-o":"\uf0e6",

"flash":"\uf0e7", # alias:bolt

"sitemap":"\uf0e8",

"umbrella":"\uf0e9",

"paste":"\uf0ea", # alias:clipboard

"lightbulb-o":"\uf0eb",

"exchange":"\uf0ec",

"cloud-download":"\uf0ed",

"cloud-upload":"\uf0ee",

"user-md":"\uf0f0",

"stethoscope":"\uf0f1",

"suitcase":"\uf0f2",

"bell-o":"\uf0a2",

"coffee":"\uf0f4",

"cutlery":"\uf0f5",

"file-text-o":"\uf0f6",

"building-o":"\uf0f7",

"hospital-o":"\uf0f8",

"ambulance":"\uf0f9",

"medkit":"\uf0fa",

"fighter-jet":"\uf0fb",

"beer":"\uf0fc",

"h-square":"\uf0fd",

"plus-square":"\uf0fe",

"angle-double-left":"\uf100",

"angle-double-right":"\uf101",

"angle-double-up":"\uf102",

"angle-double-down":"\uf103",

"angle-left":"\uf104",

"angle-right":"\uf105",

"angle-up":"\uf106",

"angle-down":"\uf107",

"desktop":"\uf108",

"laptop":"\uf109",

"tablet":"\uf10a",

"mobile-phone":"\uf10b", # alias:mobile

"circle-o":"\uf10c",

"quote-left":"\uf10d",

"quote-right":"\uf10e",

"spinner":"\uf110",

"circle":"\uf111",

"mail-reply":"\uf112", # alias:reply

"github-alt":"\uf113",

"folder-o":"\uf114",

"folder-open-o":"\uf115",

"smile-o":"\uf118",

"frown-o":"\uf119",

"meh-o":"\uf11a",

"gamepad":"\uf11b",

"keyboard-o":"\uf11c",

"flag-o":"\uf11d",

"flag-checkered":"\uf11e",

"terminal":"\uf120",

"code":"\uf121",

"mail-reply-all":"\uf122", # alias:reply-all

"star-half-empty":"\uf123", # alias:star-half-full,star-half-o

"location-arrow":"\uf124",

"crop":"\uf125",

"code-fork":"\uf126",

"unlink":"\uf127", # alias:chain-broken

"question":"\uf128",

"info":"\uf129",

"exclamation":"\uf12a",

"superscript":"\uf12b",

"subscript":"\uf12c",

"eraser":"\uf12d",

"puzzle-piece":"\uf12e",

"microphone":"\uf130",

"microphone-slash":"\uf131",

"shield":"\uf132",

"calendar-o":"\uf133",

"fire-extinguisher":"\uf134",

"rocket":"\uf135",

"maxcdn":"\uf136",

"chevron-circle-left":"\uf137",

"chevron-circle-right":"\uf138",

"chevron-circle-up":"\uf139",

"chevron-circle-down":"\uf13a",

"html5":"\uf13b",

"css3":"\uf13c",

"anchor":"\uf13d",

"unlock-alt":"\uf13e",

"bullseye":"\uf140",

"ellipsis-h":"\uf141",

"ellipsis-v":"\uf142",

"rss-square":"\uf143",

"play-circle":"\uf144",

"ticket":"\uf145",

"minus-square":"\uf146",

"minus-square-o":"\uf147",

"level-up":"\uf148",

"level-down":"\uf149",

"check-square":"\uf14a",

"pencil-square":"\uf14b",

"external-link-square":"\uf14c",

"share-square":"\uf14d",

"compass":"\uf14e",

"toggle-down":"\uf150", # alias:caret-square-o-down

"toggle-up":"\uf151", # alias:caret-square-o-up

"toggle-right":"\uf152", # alias:caret-square-o-right

"euro":"\uf153", # alias:eur

"gbp":"\uf154",

"dollar":"\uf155", # alias:usd

"rupee":"\uf156", # alias:inr

"cny":"\uf157", # alias:rmb,yen,jpy

"ruble":"\uf158", # alias:rouble,rub

"won":"\uf159", # alias:krw

"bitcoin":"\uf15a", # alias:btc

"file":"\uf15b",

"file-text":"\uf15c",

"sort-alpha-asc":"\uf15d",

"sort-alpha-desc":"\uf15e",

"sort-amount-asc":"\uf160",

"sort-amount-desc":"\uf161",

"sort-numeric-asc":"\uf162",

"sort-numeric-desc":"\uf163",

"thumbs-up":"\uf164",

"thumbs-down":"\uf165",

"youtube-square":"\uf166",

"youtube":"\uf167",

"xing":"\uf168",

"xing-square":"\uf169",

"youtube-play":"\uf16a",

"dropbox":"\uf16b",

"stack-overflow":"\uf16c",

"instagram":"\uf16d",

"flickr":"\uf16e",

"adn":"\uf170",

"bitbucket":"\uf171",

"bitbucket-square":"\uf172",

"tumblr":"\uf173",

"tumblr-square":"\uf174",

"long-arrow-down":"\uf175",

"long-arrow-up":"\uf176",

"long-arrow-left":"\uf177",

"long-arrow-right":"\uf178",

"apple":"\uf179",

"windows":"\uf17a",

"android":"\uf17b",

"linux":"\uf17c",

"dribbble":"\uf17d",

"skype":"\uf17e",

"foursquare":"\uf180",

"trello":"\uf181",

"female":"\uf182",

"male":"\uf183",

"gittip":"\uf184",

"sun-o":"\uf185",

"moon-o":"\uf186",

"archive":"\uf187",

"bug":"\uf188",

"vk":"\uf189",

"weibo":"\uf18a",

"renren":"\uf18b",

"pagelines":"\uf18c",

"stack-exchange":"\uf18d",

"arrow-circle-o-right":"\uf18e",

"arrow-circle-o-left":"\uf190",

"toggle-left":"\uf191", # alias:caret-square-o-left

"dot-circle-o":"\uf192",

"wheelchair":"\uf193",

"vimeo-square":"\uf194",

"turkish-lira":"\uf195", # alias:try

"plus-square-o":"\uf196",

"space-shuttle":"\uf197",

"slack":"\uf198",

"envelope-square":"\uf199",

"wordpress":"\uf19a",

"openid":"\uf19b",

"institution":"\uf19c", # alias:bank,university

"mortar-board":"\uf19d", # alias:graduation-cap

"yahoo":"\uf19e",

"google":"\uf1a0",

"reddit":"\uf1a1",

"reddit-square":"\uf1a2",

"stumbleupon-circle":"\uf1a3",

"stumbleupon":"\uf1a4",

"delicious":"\uf1a5",

"digg":"\uf1a6",

"pied-piper-square":"\uf1a7", # alias:pied-piper

"pied-piper-alt":"\uf1a8",

"drupal":"\uf1a9",

"joomla":"\uf1aa",

"language":"\uf1ab",

"fax":"\uf1ac",

"building":"\uf1ad",

"child":"\uf1ae",

"paw":"\uf1b0",

"spoon":"\uf1b1",

"cube":"\uf1b2",

"cubes":"\uf1b3",

"behance":"\uf1b4",

"behance-square":"\uf1b5",

"steam":"\uf1b6",

"steam-square":"\uf1b7",

"recycle":"\uf1b8",

"automobile":"\uf1b9", # alias:car

"cab":"\uf1ba", # alias:taxi

"tree":"\uf1bb",

"spotify":"\uf1bc",

"deviantart":"\uf1bd",

"soundcloud":"\uf1be",

"database":"\uf1c0",

"file-pdf-o":"\uf1c1",

"file-word-o":"\uf1c2",

"file-excel-o":"\uf1c3",

"file-powerpoint-o":"\uf1c4",

"file-photo-o":"\uf1c5", # alias:file-picture-o,file-image-o

"file-zip-o":"\uf1c6", # alias:file-archive-o

"file-sound-o":"\uf1c7", # alias:file-audio-o

"file-movie-o":"\uf1c8", # alias:file-video-o

"file-code-o":"\uf1c9",

"vine":"\uf1ca",

"codepen":"\uf1cb",

"jsfiddle":"\uf1cc",

"life-bouy":"\uf1cd", # alias:fa-life-saver,fa-support,life-ring

"circle-o-notch":"\uf1ce",

"ra":"\uf1d0", # alias:rebel

"ge":"\uf1d1", # alias:empire

"git-square":"\uf1d2",

"git":"\uf1d3",

"hacker-news":"\uf1d4",

"tencent-weibo":"\uf1d5",

"qq":"\uf1d6",

"wechat":"\uf1d7", # alias:weixin

"send":"\uf1d8", # alias:paper-plane

"send-o":"\uf1d9", # alias:paper-plane-o

"history":"\uf1da",

"circle-thin":"\uf1db",

"header":"\uf1dc",

"paragraph":"\uf1dd",

"sliders":"\uf1de",

"share-alt":"\uf1e0",

"share-alt-square":"\uf1e1",

"bomb":"\uf1e2",

}

x = 0

y = 0

w = 16

for z in fa41code.keys():

bpy.ops.object.text_add(location=(x,y*(-1),0))

ob=bpy.context.object

ob.data.body = fa41code[z]

ob.data.font=bpy.data.fonts.get('FontAwesome')

x = x + 1

if x >=w:

x = 0

y = y +1