ようやく形になった…(追記:なってない)
国土地理院の配布している行政区域データを日本地図を作成する目的でわちゃわちゃいじっておりました。SVGファイルで出力してIllustratorに持っていくのが目的です。
svgwriteやpyprojを使うことでSVGファイルへの出力は随分と前にできていたのだけど、それを直接 Illustrator に読み込むと一部うまく読み込まれないことがあり、困っていたわけです。
これがIllustratorで読み込んだ状態。佐渡市が飛び飛びの線でしか表示されていないように見えるけど、島本体のアウトラインが認識されていない状況です。で、どうにかならないかって時に、
こんな感じで、Affinity Designer ならちゃんと読み込まれたのですよ。ってことでこいつから改めてsvgを書き出してやります。
書き出したsvgファイルをIllustrator で読み込むと
今度はちゃんと読み込まれました。Affinity Desingerがいい感じのSVGファイルにしてくれたってことっすね。ってことで手順はこれで良さそうです。読み込めたと思ったんですけどねぇ。やっぱり同じように島の本島部分の要素が消えてしまいます。佐渡島と対馬に発生中。
<追記>佐渡市の本島のみ、つまり d="" の中に書かれる閉曲線の要素を一つだけにしたものを書き出したのですけど、やっぱりIllustratorでは読み込まれませんでした。そこで、その佐渡市の本島部分だけにしたsvgファイルをテキストエディタで開き、d=""内の一番最後の要素を残し、そこから前のファイル全体から見ると半分までを削除しました。ポイントの数を半減させたってことですね。そしたら読み込まれるわけです。Illustratorがデータを読み込む際、扱えるポイント数に制限があるんじゃないか疑惑が生まれています(そりゃ当然あるだろうけど、Affinity DesignerはもちろんWebブラウザでも読み込める範囲のポイント数でダメになっちゃうの?って思いますけど...もちろんBlenderも読み込める)。
Affinity DesignerからパスをコピペでIllustratorに持っていけるのだけど、佐渡市本島については島の一部が欠けた形でペーストされることからそんな予想をしてみているのですが、実際のとこどうなんでしょう。そしてそうだとするなら回避手段は無い?</追記>
余談ながら、これはテストのために新潟県だけを出したものなのだけど、svgwriteから出力されたSVGファイルは9.9MBで、それを読み込んでAffinity Desginerから書き出されたSVGファイルは2.6MBでした。お互いのファイルを開いてみたところ、Affinity Desinger産のSVGファイルのサイズが小さいのは、有効桁数が少ないのと相対位置で座標が記録されているからのようです。svgは単なるテキストファイルだから、それだけでだいぶサイズが変わってきてしまうわけっすな。
さらに余談ながら、Affinity Designerで開けたからこれで以後の作業を完結してもいいのだけど、自動処理をさせたい時(市町村ごとに違う色を割り当てたいとかしたい時)、現状手動でやらざる得ないってのは困るかなと思いました。
それから、例えば長岡市の内側に見附市の飛び地があるようなのだけど、下図の緑色領域内にある小さな黒線で囲まれた範囲ですね。そこは長岡市単体で見た時、穴になっていて欲しいわけです。
レイヤーパレット上は下図のような感じで、ここの「カーブ」って名前のサブレイヤーを選択して
レイヤー→塗りつぶしモード→交互(奇数-偶数) を選ぶことで穴が開きます。
しかしてレイヤーの構造的に長岡市グループの下にカーブレイヤーがあるもので、いちいちグループを開いてカーブレイヤーを選択しメニューを選ぶって手間を経ないといけないのですよ。長岡市だけならいいけど、当然、その他の市町村にも同様の構造のところはあるので、一括で処理したい。のだけど、グループの子供のカーブレイヤーを一括で選択するのがどうも困難らしいのです。
この辺、Illustratorだとレイヤー全部選択して属性パレットの塗りの奇偶規則を適用ボタンをオンにするだけです。
Affinity Designerで同じようにまとめて選択して適用する楽な方法ってあるんかなぁって思いつつ、Illustratorはよくできているなぁと思いました。
Blender アドオン インストール
Blender 2.82がリリースされましたが、macOS版においてはドラッグ&ドロップでアプリケーションフォルダに放り込めばいい仕様なため、つまりは特に何も気にしていない場合、旧バージョンが上書きされます。結果、
/Applications/Blender.app/Contents/Resources/2.8x/scripts/addons
に放り込んでいたアドオンは消えちゃうわけですな。
アプリケーション本体の内側をユーザにいじらせるはずがないから、これが間違ったやり方ってのはわかっていたのだけど、場所を探すのが面倒くさかったわけで…。でまぁ推奨される方法を知りたいなと思いました。
Blenderのアドオンはpythonのモジュールみたいなもののようで、__init__.py ってファイルの入ったフォルダや.pyファイルそのものをアドオンとして認識するようです。で、それを保持させる場所ってのが、ユーザフォルダ内にあったのですね。なるほど。知っとけって知識でした。
/Users/[ユーザ名]/Library/Application Support/Blender/2.8x/scripts/addons
ということで、一つ入れてみたアドオンがこちら。R_Array addon 。Githubから落としてできるフォルダをアドオンフォルダに入れてのインストールっすな。オブジェクトを円上に複数個複製するってものです。
複製する円の半径をどう決めるのかと思ったらマウスのドラッグなんだけど、画面の端までマウスカーソルが行ってしまったらそれ以上大きな円にできないじゃんって思ったら、左の画面の端に達したら右の端に現れてってのを延々と繰り返すことができました。ちょっと面白い動きですね。
余談ながらこのモデルはArchmodels vol.226 ローポリ植物セット [株式会社オークオンラインショップ] のサンプルファイルです。
BlenderのUVプロジェクションが謎
球にUVを設定し直したいだけなので、UV→Sphere Projection を実行すると、こんな空気を読めない感じのUVで展開されます。
世のBlender使いの方々は、どうやっているんでしょう (ググるとなんかすごい手順を重ねて綺麗に開くってことをやってんだけど、いやいや、コマンド一発でいきませんか?とは思います。この辺、MODO先輩はとってもお利口だし、Softimage大先輩の開き方も好みです(^^))。
簡単なスクリプトを書いてみてみた
必要に迫られて書きました。簡単と言いつつ、作法が本当にわかってないので苦労したw なぜよく分かってないツール(Blender)でやった?というのは、たまたま開いていたソフトがこれだったからぐらいの理由。
import bpy obj = bpy.context.active_object msh = obj.data thVal = 0.75 tgtPoly = [] bpy.ops.object.mode_set(mode='OBJECT', toggle=False) for poly in msh.polygons: maxVal = -100000000.0 print('poly') for i in poly.vertices: v = msh.vertices[ i ] if v.co.z > maxVal: maxVal = v.co.z if ( maxVal + 0.001 ) < thVal: tgtPoly.append( poly.index ) for i in tgtPoly: msh.polygons[i].select = True bpy.ops.object.mode_set(mode='EDIT', toggle=False)
ポリゴンを構成する頂点のZの最大値が0.75より低いポリゴンを選択する、っての。本当はある高さより低いポリゴンを削除するってのを書きたかったのだけど、消し方がわからないw
事情をもうちょっと細かく書くなら、
こんなデータをもらいました。グリッドを「個々の面で押し出し」で高さ方向に押し出して、その個々の面の高さをバラバラにして、その上で全てのエッジを選択して「辺を分離」したようなデータです。上図右側は面同士はくっついてないよ、ってもの。
こいつのある高さより低い柱を削除したい、というのが今回の命題。しかしある高さより低いポリゴンを選択して 選択→リンク で選択しようとしても全ての面が分離しているために出来ず、じゃあ近接ポイントを結合すればいいんじゃないかと思っても、根元のポイントは隣の柱のポイントと同ポジにあるために隣の柱とくっついちゃう。
故にこんなスクリプト を書きました。
ちなみにもらったデータの柱には、柱の高さごとに色を変えるための頂点カラーが設定されているため、頂点カラーごとに柱を選択して 分離→選択 してやれば色ごとの柱オブジェクトを作成可能だなってことで、そんな作業を手動で全部やりよりかは楽になる程度のスクリプト も書きました。柱ごとの色は単色の想定です。
import bpy obj = bpy.context.active_object msh = obj.data color_layer = msh.vertex_colors.active colorList = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] tgtNo = 1 #分離する頂点カラーの番号。この場合緑色の頂点カラーのポリゴンが選択される予定 tgtPoly = [] i = 0 for poly in msh.polygons: for idx in poly.loop_indices: color = color_layer.data[i].color tmp = [ color[0], color[1], color[2]] if tmp == colorList[ tgtNo ]: tgtPoly.append( poly.index ) i += 1 for i in tgtPoly: msh.polygons[i].select = True bpy.ops.object.mode_set(mode='EDIT', toggle=False)
ネット上のスクリプトのコピペの組み合わせでやってるから、細かいことがわかってない。スクリプト周りはどこを見ると勉強になるだろう。
matplotlibに敗北したのでBlenderで変形させてみる
正距円筒図法の日本地図を他の図法に変形したいわけですけど、Pythonのモジュールとしてはcartopyとmatplotlibの組み合わせでできそうだと思って格闘したんですけど、荒れた絵しか出てこないのですね。単に無知な結果なのか、そもそも無理なのか…
なので諦めて、3DCGソフトのグリッドに日本地図を貼り付けて、それを変形させることにしました。
Pythonが使えればいいのでなんでもいいんですけど、せっかくなのでBlenderで。座標変換にはPyprojモジュールを使います。
macOS上で pip3 install pyproj でOSのPythonにはそのモジュールが入りましたが、BlenderのPythonでは認識されないので一手間加えます。
Blender上で
import sys
sys.path.append('/usr/local/lib/python3.7/site-packages')
をするだけなんですけどね。これでpyprojが使えるようになりました。
ということで、突貫工事の稚拙なスクリプト。1000x1000のグリッドで実行完了まで数秒かかりますw
import bpy from mathutils import Vector, Matrix from pyproj import Proj import numpy as np #変形後の形状の東西方向のサイズ(m) gridWidth = 100.0 #日本各地の端っこ(Google mapでクリックして返ってくる値w) north = [ 45.523015 , 141.936587 ] #宗谷岬 #east= [ 43.385437 , 145.817579 ] #納沙布岬 east = [ 45.509032 , 148.893014 ] #択捉島 south = [ 24.045030 , 123.791862 ] #波照間島 west = [ 24.449230 , 122.932030 ] #与那国島 #中心地としてとりあえず明石を指定してみる。 akashi = [ 34.0 + 39.0/60.0, 135.0 ] #明石 #ランベルト正角円錐図法 #標準緯線が何が正解か分からんので、とりあえず国土地理院のページの地図の一つを参考にしている。 #https://www.gsi.go.jp/chubu/minichishiki22.html lat_1 = 34.0 + 5.0/60.0 lat_2 = 37.0 + 54.0/60.0 + 30.0/3600.0 converter = Proj( proj='lcc', R=6371200, lat_1=lat_1, lat_2=lat_2, lon_0=akashi[1], ellps='WGS84' ) obj = bpy.context.object mesh = obj.data verts = mesh.vertices xMax = -1000000.0 yMax = -1000000.0 xMin = 1000000.0 yMin = 1000000.0 vertsList = [] for vert in verts: vertPos = vert.co[:2] vertsList.append( list( vertPos ) ) if vertPos[0] > xMax: xMax = vertPos[0] if vertPos[0] < xMin: xMin = vertPos[0] if vertPos[1] > yMax: yMax = vertPos[1] if vertPos[1] < yMin: yMin = vertPos[1] newXMax = -10000000.0 newYMax = -10000000.0 newXMin = 10000000.0 newYMin = 10000000.0 i = 0 cntX , cntY = converter( akashi[1], akashi[0] ) #中心地は明石にしている for vertPos in vertsList: lon = ( vertPos[0] - xMin )/( xMax - xMin ) * ( east[1] - west[1] ) + west[1] lat = ( vertPos[1] - yMin )/( yMax - yMin ) * ( north[0] - south[0] ) + south[0] x , y = converter( lon, lat ) x = x * 0.001 y = y * 0.001 y = y - cntY * 0.001 if x > newXMax: newXMax = x if y > newYMax: newYMax = y if x < newXMin: newXMin = x if y < newYMin: newYMin = y v = Vector( ( x, y, 0.0 ) ) verts[i].co = v i+=1 sclVal = gridWidth / (newXMax - newXMin) obj.scale = ( sclVal, sclVal, sclVal )
Blenderでの操作の基本的なところ 7
Blenderのマテリアル
3DCGソフトではオブジェクトとマテリアルは別々に存在していて、マテリアルをオブジェクトに適用するとオブジェクトにそのマテリアルの質感がつくというのは割と一般的なんじゃないかと思いますけど、Blenderはオブジェクトの面に適用することになるようです。オブジェクトそのものにマテリアルを持たせる場合、それを構成しているメッシュの面全体にマテリアルを適用するということの模様。
オブジェクトはマテリアルスロットを持ち、そこからマテリアルとリンクされます。だから下図のように新規で作成されたオブジェクトにはマテリアルが存在せず、マテリアルを持たせるためにまずマテリアルスロットを追加し、そこに既存のマテリアルをリンクさせるか新規に作成したマテリアルをリンクさせるかという考え方になる様子。
既存のマテリアルは使い回しができるということが重要です。ということで、複数のオブジェクトでマテリアルを共有している時、そのオブジェクトたちのうちある一つのマテリアルを変更したらその他のマテリアルも同様に変更されるのは自明です。
あるオブジェクトに適用されている既存のマテリアルによる質感をちょっとだけ変えたいという場合、それが適用されている他のオブジェクトに影響を与えないために、マテリアルを複製してから値をいじることになるようです。
まだこんな基礎をうろうろしているw
Viz Artist 4.0 がリリースされたらしい
まぁまだフリー版は出てないし、出る予定があるかもわからないので、触れることが今後あるのかはわかりませんが、ドキュメントが見れるので眺めています。
Viz Artist User Guide - Viz Artist and Engine
いろいろ興味深いことが書かれていますね。Viz 4の最大の目玉はReality Fusion Pipelineっていう新しいレンダリングパイプラインですけど、結果としてViz 3以前とは考え方がだいぶ違うことが真っ先に記されています。またまだ実装されていない機能もいくつかある模様。
それにしても嬉しいのはポストプロセスでのエフェクトがサポートされたことでしょう。ブルーム、DOF、スクリーンスペースリフレクション、トーンマッピングがこれにより可能となるようです。この辺の制御をレンダーグラフエディタっていう新しいノードベースのエディタで行うのでしょうか。ちょっとよく分かりません。
そして、ついに実装されたPBR Materialです。例でSubstance Painterで作成されたテクスチャ素材を使用していますな。3.xで存在したSubstance Matarialを読み込むプラグインも4.0では健在ですけど、Substance Painterで作成した素材をプラグイン無しでダイレクトに読み込め活用できるようになるのはとてもありがたい。
PBRはIBLが大事ですけど、一応PBR的なことができていたViz 3.xのSubstance Plug-inにおける環境マップ用に受けられるテクスチャが8bitというクソな仕様を脱し(新しい3.x付属のプラグインには触ってないのでもしかし荒状況は変わっているかもだけど、16bit画像には対応してないのは変わってないと思うので…)、16bitテクスチャをちゃんと使用できるようになっているようです。
で、Viz 3.xまでは無かったライトオブジェクトというものが追加されました。オブジェクトとしてシーンにライトを配置するという、昨今のCG環境での普通の環境に進化しておりますw でもって影も落とせますけど、パラメータの考え方はUnityなんかのと同じような感じすかね。ただ、オブジェクトが影を発生させたり受ける場合にはキャスター、レシーバの設定をオブジェクトごとにしないといけない模様。この辺の考え方はViz 3.xと変化がないということになります。まぁ重くなりますしねぇ。
GIについてはViz 3.9以降のものの改良版ということです。使ったことがないので、演算速度がどんなもんなのか気になりますな。
とはいえ、従来のViz 3.xの「このレベルのことしか表現できないけど、その代わりめっちゃ簡単だよ」ってところと比較してだいぶ複雑になることが予想されます。いろいろと覚えなおしたり新規に学ばねばならない範囲が広そうで、移行には相応の労力が必要そうですね。
ん?スクリプトはVBの構文のままですか。まぁ学習コストが低くなんでいいけど…
静止画に対するカメラマッチ
fSpyってオープンソースのツールがあるようです。
で、そのデータをインポートするためのBlenderのAddonが公式にリリースされています。
fSpy-Blender[GitHub]
Addonのインストール手順、使用方法が書かれているページは こちら[GitHub]。
軽く使ってみました。
非常に簡単な印象で、写真をドラッグ&ドロップでアプリケーションのウインドウに放り込んだら、あとはxyzの三軸のうちの二軸に平行な線を2本ずつ引っ張ってやるだけです。その他細かい設定もいくつかありますけど(引っ張った線がプラス向きかマイナス向きかとか、距離を参照するラインの長さを指定したりとか、カメラのセンサーの中心が画像のどこに一致するかを指定したりとか(通常これは画面中央)、原点位置を指定したりとか)、まぁまぁシンプルかと思います。なを各ポイント位置を設定するとき、Shiftキーを押しながらドラッグするとそのポイント中心を拡大した状態で作業ができるので、より精密に設定するときにはそうすべきですね。
そうして設定したらFile→Saveで保存すると、拡張子 fspy のファイルが出来上がりました。これをBlenderに読み込みます。
カメラが作られ、pSpyで計測された設定がそれに対して行われ、かつ Background Images も設定された状態になりました。
個人的にはMODOに同様の機能があるからそっちでやってもいいのですけど、Blenderにデータを持ち込むならこっちが手軽でいいかもしれないと思ったので、おぼえておくこととしましょう。
Google Earth Studio をちょっと触ってみた
今頃?って感じですけど、Safariで動かないってこともあり、申請はしたけど放置しておりました。
Google Earth自体はプロ版をダウンロードしてスタンドアロンのアプリとして利用可能だけど、フライスルーの映像を作成するにはかなり使いづらいと言わざる得なかったところに、カメラアニメーションのためのGUIを乗っけたWebアプリとして登場して一時期話題になっていました。
実際触ってみるとなかなかよくできています。カメラワークを、3DアプリとかAfterEffectsのようなソフトを触っている人なら、かなり直感的につけられるような気がしますね。
Google Earth Studio Test Movie
AEへのカメラのエクスポートもできるようなので、レンダリングした画像にさらに一味乗せることも可能である、と。
もちろん、Google Earth Studio内である程度の要素なら加えることが可能っぽいです。
その上でレンダリングを行うわけですが、これはローカルPCのマシンパワーを使うんでしょうね。とはいえ、CPUをフルに使っちゃうということもないので、裏でTwitterでも見ながらレンダリング終了を待つということは可能。もっともMac版では、他のアプリを全画面にして使っちゃうと(アクティブにしちゃうと)レンダリングが止まっちゃうようでした。
そうして出力したムービーが上の動画です。
問題はライセンスですね。せっかく作っても公開できないんじゃ価値が半減です。ニュースや学術調査、教育と非営利目的では無料で利用できるようです。問題は商用利用で、例えばバラエティ番組で日本列島から山中の一軒家に突っ込んでいくような動画が必要になったときに利用できるのか。おそらくテレビ局はGoogle Earthの利用に関してGoogleと契約を結んでいるでしょうから、Google Earthを使っていいよってなっているのなら使えるんじゃないかと思うのだけど、それを納品するところにちゃんと確認をしないと不味そうです。少なくともフリーの人が自分の責任でテレビ番組とかに納品するなんてことは危険そうだなぁという気はしますが、さてさて。
ユーチューバーが自分の番組のために作成した時とかどうなんだろうなぁ(これは商用って括りなのか?)
Blenderでの操作の基本的なところ 6
Blenderでシーン内の構造を俯瞰する仕組みとして Outliner がありますが、ちょっとわかりにくかった。
Blenderを起動した時のデフォルトの画面は、Scene Collectionの子供にCllectionがあり、その中に Camera, Cube, Light が存在している、ように見えます。
単純にMayaにおけるOutliner, SoftimageにおけるExplorerのScene_Rootからの階層が表示されるモードなのかなぁって思っていたのだけど、ドラッグ&ドロップによる親子関係の構築ができないじゃありませんか。
この画面は View Layer を表示している画面、ということでございました。View Layerはレンダリングの単位として考える模様。SoftimageにおけるPassの編集画面といったところでしょうか。
とはいえ、よくわからんので一つずつ調べてみたいと思います。
blendファイル
Blenderが生成するファイルは.blendって拡張子がついていますが、この中身をリスト化して表示する機能を持つものが Outliner ということになります。このファイル内はデータベースになっているそうです。
コレクションとシーンとオブジェクト
そのblendファイル内にシーンが格納されているコレクションがあるようです。それとは別にオブジェクトを格納しているコレクションがあります。そのコレクション内のオブジェクトをシーンは参照しているという形になるようです。
blendファイル内の全構造を俯瞰しようとしたら、Outliner で Blender File を選択すると見ることができるようです。
このうち、Sceneのコレクション Scene Collection に所属する連中を表示するのが Scene を選ぶことで表示されるモードということになるのでしょうか。
この画面の中ではドラッグ&ドロップで親子関係をいじることができました。シーン内の階層構造を管理したいという時にはこの画面が一番しっくりくるような感じです。
ちなみに、一つのblendファイル内に複数のシーンを持たせることが可能の模様で、興味深い使い方ができそうです。
グループ機能としてのコレクション
で、blendファイルにデフォルトで用意されるコレクションのほかに、シーン管理において、オブジェクトをまとめるグループとしての機能を持つコレクションを作成することができます。これはScene Collectionの子供として作成され(デフォルトで一つ存在し、シーン内の既存のカメラやライト、キューブはとりあえずそこに所属する)、一つのオブジェクトは複数のコレクションに所属させることができるというわけで、Softimageのグループに近い概念で取り扱えるのかもしれません。
View Layer
ビューレイヤーはレンダーレイヤーと過去呼ばれていたものが機能を拡張してリネームしたものということです。
複数のビューレイヤーを作成可能で、それぞれのビューレイヤーにはコレクション単位での所属・非所属を設定し、ビューレイヤーごとにレンダリングするパスを設定できる模様。
ビューレイヤーごとの出力ファイルの設定をいじるにはどうすんのとか疑問は多々あるけど、とりあえずモデリング時とかは Outliner を Scene の状態で使うのが良さそうかなという結論を得て、とりあえずこれぐらいにしておいてやることにします。