3Dモデルをいろいろ作ってみたい

3Dモデルをいろいろ作ろうとがんばっています。苦労した点、役に立ちそうな情報を発信していきます。

立体地図を作る -標高で色分け試作-

DMM.makeに造形を依頼していた静岡県の立体地図が届きました。最初アップロードしたデータにはちょっと不備があったのですが、担当者のかたがメールでの問い合わせにも迅速に応えてくれて修正することができました。

f:id:ichidaya:20190128120720j:plain

静岡県マルチカラーアクリル

今回は縦方向の縮尺比率を横方向の3倍におさえています。前回、近畿地方中心の7県をナイロン製で造形したときは10倍にしていたのですが、10倍だと富士山が異様にとんがってしまい美しいフォルムにならなかったです。

実は今回の造形では真ん中あたりに水平方向のスジがはいってしまったのですがこれは色付けとは関係なくて、静岡県は以前の7県と違って3Dモデルを2つに分けて作成したことが原因です。OpenSCADで処理できるデータの量に制限があり2つのSTLファイルに分けて生成、それらをOBJ形式に変換し、(大きなデータを処理できる)ZBrushに読み込んで統合と編集・改めてSTLファイルを出力、といった手順をとったらこんなスジがついてしまいました。その後、OpenSCADを使わずに大きめのデータでもいっきょにOBJ形式データを生成する方法にめどがたったので機会があれば紹介したいと思います。

 

 

標高テクスチャ付き立体地図モデル

作成した地図モデルに標高で色分けしたテクスチャ画像を貼り付けてみました。

f:id:ichidaya:20190118133810p:plain

標高テクスチャの貼り付け

ZBrushの機能でUV展開はできますが、画像を標高で塗り分けるのを手作業で行うのは難しいのでGimpプラグインプログラムでテクスチャ画像を生成しました。

f:id:ichidaya:20190118165654p:plain

UVマッピングにそって塗り分けたテクスチャ画像

 

DMM.makeにマルチカラーで造形を依頼中。どんなできあがりになるか楽しみです。

 

立体地図を作る -補足1 パズルのピースとして形を整える-

都道府県ごとに立体地図をモデル化したのは各県をピースとしてジグソーパズルにするという目論見がありました。正確な行政区画のとおりに輪郭を作ってしまうと県境が細かく互いに入り組んでしまってピース同士をはめ合わせることが難しくなってしまいます。そこで、行政区画を参考にしながら、もっと単純化した図形でポリゴンを手作業で作成しこのポリゴンに従って標高メッシュを切り分けることにしました。

参考にするのは「その2 行政区画情報の準備」でQGISにとりこんだ国土地理院の行政区画情報です。フィールド計算機を使って新しいフィールド都道府県を追加してうえで参考にしやすいよう県別に地図を色分けしておきます。

(1)行政区画のレイヤを選択した状態でレイヤパネル左上の「レイヤスタイルドックを開く」アイコンをクリックしてレイヤスタイルドックを開く

(2)レイヤの種類で「分類された」を選択

(3)カラムをクリックして都道府県のフィールドを選択

(4)分類ボタンをクリック

以上の操作により都道府県ごとの色分けが行われます(下図参照)。

f:id:ichidaya:20181226001746p:plain

都道府県ごとの色分け

 色分けされた行政区画を見ながら新たに自分で都道府県の輪郭を示すポリゴンを作成していきます。まず、ポリゴン作成用のレイヤを新規作成します。

(1)レイヤ->レイヤの作成->新規シェイプファイルレイヤをクリック

(2)ダイアログでタイプ:ポリゴンを選択、新規フィールドとしてテキスト型の「都道府県」というフィールドを追加

(3)OKをクリック、シェイプファイルの格納場所を聞かれるのでファイルパスを指定してOKをクリック

f:id:ichidaya:20181226154448p:plain

新規ポリゴンレイヤの作成

新しく作ったレイヤを選択した状態でポリゴンを作成するのですがその前にスナップの設定をしておきます。これを設定しておくと隣り合う県のポリゴンの境目部分をぴったり合わせることができます。設定->スナップオプションをクリックします。

f:id:ichidaya:20181226185300p:plain

スナップの設定

表示されたダイアログ上で該当レイヤに対してスナップの許容範囲(0より大きい値)と交差の禁止を指定します。このとき他のレイヤに対して交差の禁止が指定されていないことを確認しておいてください。他のレイヤに対して交差禁止を指定しますとポリゴン作成時に「交差回避によりジオメトリが壊れているので地物を追加できません」というエラーが頻繁に発生してしまいます。

ポリゴンの作成にはQGISウィンドウの左上にアイコンがある3つの機能(青枠で囲った左から「編集モード切替」、「地物の追加」、「ノードツール」)を使用します。

f:id:ichidaya:20181226174558p:plain

ポリゴン作成に用いる機能のアイコン

(1)編集モード切替アイコンをクリックしてポリゴンの入力・編集を可能にする

(2)地物の追加アイコンをクリック後、都道府県のかたちに沿って点をクリックしてポリゴンを定義する

(3)右クリックで形の定義を終了させ、idと都道府県名を入力する。

実際には(2)の操作だけで所望のかたちに作るのは難しいので四角形など単純なポリゴンをいったん作ってから、ノードツールを使って複雑な形状に編集していきます。ノードツールのアイコンをクリックすると、ポリゴンに対して頂点の追加・削除や頂点の移動ができるようになるので、これらの操作を行って都道府県を示すポリゴンをレイヤに追加していきます。

f:id:ichidaya:20181226194052p:plain

都道府県ポリゴンの作成

 各ポリゴンには属性として都道府県名が付加されているので「その3 標高メッシュの作成」に記載されているようにベクタ->データマネジメントツール->属性の結合によって行政区画のベクタレイヤの属性を標高メッシュのベクタレイアの属性に結合します。このときのダイアログで

f:id:ichidaya:20181227000110p:plain

ベクタレイヤ間での属性結合ダイアログ

ジオメトリの述語で「範囲内」のみを指定しておくと行政区画のポリゴンの線と交差・接触する境界上のマス目はは結果から除外されるので、都道府県をピースとしたときのはめ合わせに一定のクリアランスを確保しています。

f:id:ichidaya:20181227000728p:plain

標高メッシュと行政区画の結合結果

この結果の属性テーブルの情報をExcel経由でOpenSCADにとりこみ(その4 3Dモデルの生成に記述したように)3Dモデルを作成することができます。

 

f:id:ichidaya:20190104151929p:plain

府県ごとに分かれたピース

 

立体地図を作る -その4 3Dモデルの生成-

4.3Dモデル(STLファイル)の生成

前節(3.標高メッシュの作成)で得られた奈良県のメッシュのマスの数は58,000弱ありました。モデリングツールのユーザーインターフェースで1個ずつマス目ごとの高さを指定していくわけにはいかないのでデータから自動的にモデルを生成する仕掛けが必要です。今回はOpenSCADというプログラミングで3Dモデルを作成するツールを使いました。

OpenSCAD - The Programmers Solid 3D CAD Modeller

OpenSCADではテキストエディタ

translate([0.25,21.25,0]) cube([0.25,0.25,30.84]);

 といった1行のコードを記述すると、このコードで指定された場所(0.25,21.25,0)で指定された大きさ(0.25,0.25,30.84)の直方体の3D情報を作成することができます(数字の単位はmm)。人がコード(条件分岐や繰返しなどの論理構造も記述可能)を書いていくのが通常のOpenSCADでのモデリングのやりかたなのですが、今回はExcelのマクロを使ってコード列を自動で発生させることにします。

まず、奈良県のメッシュの属性テーブルの全行のデータからxmin(各マス目の左下隅の経度)とymin(各マス目の左下隅の緯度)のそれぞれの最小値を求めてこれをOpenSCADで座標を指定する際の原点とします。原点座標を(135.5405,33.8596)としてある行(1個のマス目)の情報が以下であったとすると

xmin(マス目の左下隅の経度)=135.5430

ymin(マス目の左下隅の緯度)=34.0721

標高mean(マス目内の標高平均値)=1025.0

translate([(135.5430-135.5405)*100,(34.0721-33.8596)*100,0]) cube([0.0025*100,0.0025*100,1042/50+10]);

として青色部分を計算すれば底辺をこのマス目として標高平均に対応した高さを持つ直方体を生成するコードになります。上記の式で100は横方向の縮尺、50は縦方向の縮尺、10は地図の土台部分の高さを指定するパラメータになります。

標高メッシュの属性テーブルの値をExcelに取り込んでからマクロで上記のようなコマンド列を発生させOpenSCADのエディタにCopy&Pasteに貼り付けて実行すればSTL形式で出力可能な3Dデータが生成されます。

ただし、OpenSCADは一度にあまり大量のデータを処理できない(19,000行ぐらいを超えると異常終了してしまう)ので、前節で作成した奈良県のメッシュデータについては10,000行ずつに分けてSTLファイルを生成し後からそれらを結合しました。

f:id:ichidaya:20181219003948p:plain

最初の10000個データの生成

コードを貼りつけたら画面上部のアイコンをプレビュー(1)、レンダリング(2)、STL出力(3)の順番でクリックして3Dデータを生成、格納します。プレビューはすぐに表示されるのですが、2番目のレンダリング処理には少し時間がかかります。私の環境((Intel i5-6500@3.2GHz, Memory 16GB))だと、10,000個のメッシュのレンダリングに20分ぐらいかかりました。

OpenSCADが出力するファイルの形式はSTLだけですが、このファイルを例えばMeshLabを使ってOBJ形式など別の形式に変換することができます。

MeshLab

MeshLabで取り込んだ奈良県の立体地図モデルは下の図のようになります。

f:id:ichidaya:20181222230034p:plain

奈良県の立体地図

この地図のメッシュは緯度・経度を0.0025度ずつのマス目で分割しており、それを1辺0.25mmの正方形としてモデル化しています。縮尺としては111万分の1くらいで奈良県を上から見たとき縦横の一番長い部分で縦9cm、横6cmぐらいになります。一方、垂直方向は5万分の1の縮尺で高さを計算しているので、標高の変化をかなり強調したモデルとなっています(ここで説明に用いたモデルの縮尺は「その1」で写真を載せたモデルとは異なっています)。

たいていの3DモデリングソフトはOBJ形式の3Dモデルを読み込むことができます。私の場合、OBJ形式になった3DモデルをZBrush(有料ですがプロも使っている高機能ソフトとしては安価なほうだと思います)で編集して、底面に都道府県名を彫り込んだり、細かい凹凸にスムージングをかけたりしています。今回のような作り方だと、山の峰の先端部分が厚みがなくなって3Dプリンタだと造形できない部分が発生したりするのですが、ZBrushのスムーズブラシで全体を軽く処理することで造形できるようになりました。

 

 

 

立体地図を作る -その3 標高メッシュの作成-

3.標高メッシュの作成

Jaxaのデータは30m×30m単位で標高が記録されていますが、そのままでは3Dプリントするのには細かすぎるのでもう少し大きめのメッシュを生成しその領域内の標高の平均値を割り当てます。ベクター>調査ツール->ベクタグリッドコマンドでメッシュを生成します。下記の例ではメッシュのサイズは緯度と経度それぞれで0.0025度ずつにしています。私の環境(Intel i5-6500@3.2GHz, Memory 16GB)ではあまり広い範囲に対して一度にメッシュを生成しようとすると(おそらくリソース不足で)ハングしてしまったので部分的に(奈良県を覆う程度の)範囲を指定してメッシュを作成しています。メッシュの情報も1つのレイヤとして生成されますのでこの時点で標高データを表すラスタレイヤと行政区画を表すベクタレイヤ、今作成したメッシュを表すベクタレイヤの3つのレイヤが存在することになります。

f:id:ichidaya:20181216111305p:plain

メッシュレイヤの生成

次にラスタ->地域統計->地域統計コマンドでメッシュごとの標高の情報(平均値や最大、最小、最頻値などを指定可能)を抽出しメッシュレイヤに属性として追加します。地域統計がメニューにでてこない場合はプラグイン->プラグインの管理とインストールの機能で活性化してください。

処理が終わるとメッシュのレイヤのマス1つ1つにラスタレイヤから抽出された標高の情報が属性として追加されます。下の属性一覧表で青色の枠部分はレイヤ生成時に付加されたメッシュの位置、大きさの情報、赤枠の部分は地域統計コマンドによってラスタレイヤから抽出された標高情報を示しています。属性の情報はCopy & PasteでExcelなど表計算ソフトに取り込むことができます。

f:id:ichidaya:20181216113533p:plain

標高データ追加後の属性テーブル

 続いて標高メッシュの属性に行政区画情報をマージします。ベクタ->データマネジメントツール->属性の結合によって2つのベクタレイヤの属性を結合します。この機能は2つのベクタレイヤに属する図形間の位置関係(「交差する」とか「重なりがある」)にもとづいて対応がとれた図形がもつ属性をもう一方にコピーします。

f:id:ichidaya:20181216150101p:plain

属性の結合ダイアログ

Runボタンをクリック後、結合後のレイヤの属性テーブルを表示すると各マスの位置情報と標高情報に加えて、行政区画の情報(下図の赤枠部分)が追加されていることがわかります。

f:id:ichidaya:20181216153940p:plain

行政区画の情報が追加された属性テーブル

 Copy & PasteでExcelに取り込んでフィルタで都道府県=29の行を選べば奈良県の標高メッシュが得られます。

立体地図を作る -その2 行政区画情報の準備-

2.行政区画情報の準備

行政区画の情報は国土地理院がWebで提供している基盤地図情報(基本項目)をダウンロードして用います。

基盤地図情報ダウンロードサービス

対象となる地域を選んでダウンロードします。

f:id:ichidaya:20181214160657p:plain

行政区画マップのダウンロード

ダウンロードしたファイルはGMLというXMLベースの形式で記述されておりこのままではQGISに読み込むことができません。国土地理院が提供している基盤地図情報ビューアというソフトで読み込んで QGISで利用可能なshape形式に変換します。基盤地図情報ビューアは国語地理院の以下のページからダウンロードすることができます。

各種資料|基盤地図情報ダウンロードサービス

ダウンロードしたファイルを解凍すると何種類かのXMLファイルが生成されますがそのなかの「FG-GML-??????-AdmArea-????????-????.xml」という名前のファイルだけを選んでビューアに取り込みshape形式のファイルとしてエクスポートします。これでQGISに読み込んで行政区画を表示することはできるようになるのですが、座標参照系がJAXAの標高データと異なるのでこのままでは両者の突合せを行うことはできません。QGISでいったん読み込んだレイヤを「名前をつけて保存する」で保存すると保存時の座標参照系(CRS)を指定できるのでWGS 84(EPSG:4326)を指定して保存し以後の作業ではこちらを使います。

QGISで業績区画のレイヤを選択、右クリックメニューの「属性テーブルを開く」で行政区画の線分を示すベクトルデータが行ごとに表示されます。このうち行政コードのフィールドが市区町村を表しており、上2桁が都道府県を表すコードになっています。属性テーブルの「フィールド計算機を開く」機能を使って新しいフィールド都道府県を作成しておきます(赤枠で囲った部分が追加されたフィールド)。

f:id:ichidaya:20181216001022p:plain

都道府県を示すフィールドの追加

都道府県フィールド追加後のレイヤを右クリックしてメニューのフィルタ(クエリビルダ)を使って表示する地域を絞り込むことができます。

f:id:ichidaya:20181216002801p:plain

クエリビルダのダイアログ

この例では都道府県のコードが29(奈良)である行政区画のみをフィルタすることで奈良県に該当する領域(下図の緑色の部分)のみを表示させています。

f:id:ichidaya:20181216003046p:plain

行政区画レイヤの奈良県部分のみを表示

これで標高データのメッシュと行政区画を突き合わせる準備が整いました。