Blenderの日本語文字を3Dプリントできる実体にする2つの手順
Blenderで日本語の文字を立体にして3Dプリントしようとすると、たいてい途中で止まります。テキストをメッシュに変換したところまでは見た目どおりなのに、スライサに渡すと形になっていない、という止まり方です。
原因はテキストからメッシュへの変換が、面を溶接しないまま作られることです。見た目は立体でも閉じた実体になっていないので、変換直後のメッシュは非多様体です。
直し方は分かっていて、包含ボックスとのINTERSECTに通すことです。ただしこれはBoolean演算なので、Booleanをこれ以上かけられない相手には使えません。そこで経路が2つに分かれます。この記事は、その2つと使い分けの基準、そしてBooleanを使えない側で実際に残った欠陥の記録です。
いずれも2026年7月の作業です。1/64ミニカー用の道路標識に文字を入れたときと、駐車床に「軽」の1文字を凸で入れたときの記録から起こしています。
結論:2つの経路と、どちらを使うか
| 経路A:包含ボックスとのINTERSECT | 経路B:別アイランドとして結合 | |
|---|---|---|
| 使える相手 | Booleanをかけても平気なメッシュ | すでにBooleanで荒れているメッシュ |
| やること | 文字を丸ごと含む箱を作り、交差を取る | 文字を単独で作って検証し、母材へ島として足す |
| 水密になるか | なる(Booleanの出力が閉じるため) | ならない。文字メッシュの素性がそのまま残る |
| この記事での実例 | 標識の文字(独立した小部品) | 駐車床の「軽」(既存の大きい床へ追加) |
| 残った問題 | — | 辺長0.028mmの未溶接頂点。後述 |
経路Bを選ぶ判断は「Booleanをかけたくないから」という消極的な理由です。実際の記録では、対象の床が直近数日で何度も部分パッチのBoolean処理を経ていて、これ以上Boolean modifierを直接かけると非多様体が急増するか無反応になると判断して避けています。判断は当たっていて、Boolean由来の新規破損は1件も出ていません。代わりに別の欠陥が出ました。
共通の前段:フォントを読んで、メッシュにして、寸法を合わせる
日本語フォントは .ttc のまま読める
macOSのシステムフォントをそのまま指定できます。
fnt = bpy.data.fonts.load("/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc")
.ttc は複数の書体をまとめたファイルですが、展開せずに fonts.load() へ渡して読めます。今回はどちらの部品でもヒラギノ角ゴシック W6 を使っています。
GUIを開かずヘッドレスでも同じように通ります。
/Applications/Blender.app/Contents/MacOS/Blender --background <blend> --python <script.py>
拡縮は文字高さを基準にする
テキストオブジェクトに本文とフォントを与え、中央揃えにしてから convert(target='MESH') でメッシュにします。押し出し量はこの時点では仮でよく、あとで厚みを目標値へ正規化します。
拡縮は文字高さを基準にします。日本語は字によって字幅が変わるので、幅を基準にすると文字列ごとに大きさが揃いません。ただし収めたい枠に幅の上限があるときは、高さ基準で出した倍率が幅をはみ出す場合だけ幅で拘束し直します。実際に使っている値です。
| 部品 | 文字 | 指定した高さ | 幅の上限 |
|---|---|---|---|
| 駐車床の区画表示 | 「軽」1字 | 12.0mm | —(結果 12.07 × 12.0mm) |
| 道路標識の文字 | 3字 | 2.3mm | 6.6mm |
溶接と法線の整理は、やっても水密にならない
変換直後のメッシュに、まず次を掛けます。
- 重複頂点の溶接(
remove_doubles、許容差 0.0005mm) - 縮退した辺の除去(
dissolve_degenerate、許容差 1e-5) - 面に属さない孤立頂点の削除
- 法線の再計算と、外向きになっているかの確認
ここまでやっても水密になりません。 面が溶接されていない状態は、この手当てでは解消しません。ここから経路が分かれます。
経路A:包含ボックスとのINTERSECTで実体に作り直す
文字のバウンディングボックスを少し大きく作って、それとのINTERSECT(交差)を取ります。
やっていることは「文字を丸ごと含む箱と、文字の共通部分を取る」だけなので、形は1ミリも変わりません。それでも結果は水密な実体になります。Boolean演算の出力が閉じた多様体になるからです。
余白(pad)は 2.0mm 足しています。箱の面が文字の面に接すると、接線が一致したBooleanになって別の壊れ方をするので、箱は文字から離すべきです(記録に残っているのは 2.0mm という値そのもので、この理由づけはBooleanが壊れる条件の側から補ったものです)。
この「非多様体の殻を包含ボックスとのINTERSECTで実体に作り直す」手は、テキスト以外にも使えます。
なお、文字を立てて使うために向きを変えるときは、座標の入れ替えではなく回転で変えてください。理由と症状は同じ記事にまとめてあります。
経路B:Booleanを使わずに島として足す
母材がもうBooleanを受け付けない場合は、文字を完全に独立したメッシュとして作って単独で検証し、母材へ別アイランドとして結合します。Boolean modifierは1回も使いません。
この方式の弱点は明快で、文字メッシュの素性がそのまま残ることです。経路Aの実体化を通していないので、テキスト変換由来の壊れ方が持ち込まれます。実際に持ち込まれました。
Blenderの検査は通ったのに、STLでは壊れていた
「軽」を2つの床に足したとき、Blender側(bmesh)の検査では非多様体エッジの総数が追加前後で同じで、島の数も想定どおりに増えていました。ツライチも誤差0.001mm以内でした。
それでもSTLを直接パースして辺の共有数を数えると、文字の画の角に未溶接の極小な重複頂点が残っていました。
| 検査 | 結果 |
|---|---|
| bmeshの非多様体エッジ | 総数は追加前後で同じ |
| 島の数 | 想定どおり増加 |
| 文字上面と周囲床のツライチ | 誤差 0.001mm 以内 |
| STL直接パースでの辺共有数 | 不正なエッジあり。辺長 0.028mm と 8µm 程度 |
2つの床で同じ座標に同じ欠陥が出ていました。字形が同じなら、同じ画の角で同じように壊れます。
「総数が変化なし」は根拠にならない
上の表の1行目は、本当は検査として不十分です。
同じ床に対する直前の作業(矢印の追加)で、まさにこれが露呈しています。非多様体エッジの総数は前後とも同じ本数でしたが、内訳を精査したところ追加箇所の外にあった既存の不良三角形3枚が偶然消滅して、多重度のパターンが入れ替わっていました。総数が一致したのは偶然です。そのときの申し送りに「今後『変化なし』を報告する際は総数だけでなくエッジ内訳の同一性も確認すること」と書いてあり、「軽」の記録にはその内訳確認の記述がありません。
この型そのものは3Dモデルの寸法検証が嘘をつく7つの場面に別途まとめています。文字は、この型を最も踏みやすい形状です。画の角が多く、しかも欠陥が0.03mm級なので、総数を見ているだけでは絶対に気づけません。
溶接の許容差は0.003mmでは足りなかった
直し方は、欠陥の周辺だけに限って重複頂点の溶接を掛け直すことです。ここで許容差の選び方が効きました。
| 溶接の許容差 | 結果 |
|---|---|
| 0.003mm | 不十分。 辺長 0.028mm を溶接できず残る |
| 0.05mm | 解消。文字の範囲内の不正なエッジが 0 件になった |
0.05mm まで上げても字形は崩れません。この大きさの漢字ならストローク幅が最小でも約1mmあり、その20分の1だからです。逆にいえば、もっと小さい文字では同じ手が使えません。
溶接した頂点は片方の床で273個でした。文字を足して増えた三角形数(10,832 → 16,790)は、溶接後に 16,228 へ減っています。
おまけ:無関係な場所の数が動く
STLを再出力すると、文字とは関係ない場所の不正なエッジ・縮退三角形の数が動きます(一方の床で 20 → 52、他方で 4 → 77。記録はこの2指標をまとめて数えているので、どちらの数がどの指標かは一意には読み取れません)。内訳を見ると全て文字の範囲外で、しかも既に分かっていた瑕疵のある区域に限られていました。新しい座標での発生はゼロです。
これは、n-gon(5角以上の面)が多いメッシュだとメッシュ化のたびに三角形分割の切り方が変わるためです。数が動いたこと自体を欠陥と読まないこと。 どこで動いたかを座標で見る必要があります。
文字の大きさと凸量:設計時に置いた値
ここは実印刷での確認がまだ済んでいません。 以下は設計時に置いた値と、その決まり方です。閾値として読まないでください。
| 項目 | 値 | この値がどう決まったか |
|---|---|---|
| 文字の凸量 | 0.2mm | 積層ピッチと同じ=1層。同じ床の矢印・破線と統一した設計判断 |
| 漢字1字のサイズ | 12.0mm角 | 置く区画が 33 × 35mm。そこへ収めた設計判断 |
| そのときの最小ストローク幅 | 約1mm | 上のサイズにおける字形からの値(溶接許容差0.05mmの妥当性を説明する文脈で出てきた数字) |
| 出ないと判断した線幅 | 0.3mm | 別部品の細い欧文ワードマークを、ノズル0.4mmでは出ないと見て設計から落とした |
この4つから印刷可否の閾値は出せません。 0.3mmは刷らずに落とした値、1mmは刷る前の字形の値で、しかも別々の部品の話です。「何mmまで出るか」を知りたい場合、この記事は答えを持っていません。
まだ確認していないこと
- 凸0.2mm・最小ストローク約1mmの漢字が、読める字として出るか。 未印刷です
- ストローク幅 0.3mm と 1mm の間のどこが境目か。0.3mmは設計から落とし、1mmは通した、という2点しかありません
- 道路標識側は高さ2.3mmで3字を入れる設計です。単純に比を取るとストロークは0.2mm前後になるので字としては出ないと推測していますが、これは推測で、刷っていません
- 凸ではなく凹(彫り込み)にした場合の下限。試していません
- 経路Bで残った0.028mm級の欠陥が、そのままスライサに渡ったとき実際に印刷結果へ影響するのか。溶接して消したので、放置した場合を確かめていません
細かいが引っかかる点
検算の許容差を1e-6にすると健全な形状でも落ちる
Blenderの頂点座標は単精度(float32)です。中心位置や幅を 1e-6 の許容差で検算すると、正しく出来ている形状でも不一致と判定されます。1e-3 まで緩める必要がありました。
共線の頂点から面積ゼロの三角形が生まれる
押し出しの前後のキャップを三角形分割するとき、一直線に並んだ頂点があると面積ゼロの三角形が作られます。文字の輪郭には直線区間が多いので普通に起きます。キャップだけ張り替えて潰します。
検証環境
- Blender 5.1系(macOS。ヘッドレス実行を含む)。2026-07-24の作業分は細かい版を記録に残していません
- フォント: ヒラギノ角ゴシック W6(
/System/Library/Fonts/の.ttc) - 想定していた印刷条件: Bambu Lab A1 / ノズル 0.4mm / 積層 0.2mm。この記事で扱った2部品は、いずれも実際に刷った記録がありません
- メッシュの検査結果(辺長・頂点数・三角形数・溶接の許容差・寸法)は実作業の記録から取った値です。文字の大きさ・凸量・線幅は設計時の判断で、実印刷での確認は済んでいません。
この記事で扱っている部品は市販ミニカーの道路システムと接続する互換パーツで、メーカーの公式品・許諾品ではありません。本文中の製品名・会社名は各社の商標です。寸法・手法はいずれも当方の環境での記録です。