#CGソフトにShapefileを取り込みたい
建築系CGプロダクションで働く3DCGモデラーです。
建築CGを制作していると、時々、シェープファイル(.shp)をCGソフトに取り込みたい時があります。
地図なんかを取り込みたいときです。
GIS系のソフトは持ってないけど、何かお手軽に取り込むことは出来ないか?
というときに使える方法を紹介します。
##Python + pyshp
CG系のソフトはスクリプティング環境としてPythonを使えることが多いです。
Pythonには pyshp というシェープファイルを扱うライブラリがあるので、それを使って.shpファイルを取り込めます。
pyshp
#Maya
この記事ではMayaに.shpファイルを取り込み、Curveとして描画する方法について書きます。
###pyshpをMayaへインストール
まず、Maya上のPythonである、"mayapy"にpyshpをインストールします。
cd "C:\Program Files\Autodesk\Maya2018\bin"
"mayapy.exe" -m pip install "C:\Users\Takeharu\Documents\maya\3rdParty\pyshp-2.1.0.tar.gz"
###スクリプティング
そしてMaya用のPythonスクリプト。
# -*- coding: utf-8 -*-
import pymel.core as pm
import shapefile
import os.path
# ファイルオープンダイアログ
def get_file():
startdir = ''
if pm.optionVar( exists='defaultStarDirectoryOfImportShapefile' ):
startdir = pm.optionVar( q='defaultStarDirectoryOfImportShapefile' )
else:
startdir = 'C:/Users/Takeharu/Documents'
fn = pm.fileDialog2(fileMode=1, caption="Open Shape File...", fileFilter="*.shp", startingDirectory=startdir, okCaption='Open')
pm.optionVar( sv=('defaultStarDirectoryOfImportShapefile', os.path.dirname(fn[0])) )
return fn[0]
file_path = get_file() # ファイルパス取得
with open(file_path, "rb") as myshp: # ファイルを開く
r = shapefile.Reader(shp = myshp) # リーダー
if len(r.shapes()):
pm.refresh(suspend=True)
grp = pm.group(empty=1,name='shp_group0')
crvs = []
for s in r.shapes():
t = s.shapeType
if t == 3 or t == 5: # 今回は地図をCurveで描画したいだけなので、シェイプのタイプを 3:Polyline、5:Polygonに限定します。
mapped = map(lambda x: x+(0.0,), s.points) # 元が2D座標データなので、Z軸座標を追加して3次元座標に変換します。
crv = None
if len(s.parts) == 1:
crv = pm.curve(p=mapped,d=1)
crvs.append(crv)
else: # ひとつのシェイプに複数のPolygonが含まれることがあります。それ切り分けます。
# parts`が[0,256,150] みたいなリストなら、複数のオブジェクトを内包しています。
# 数字は座標リストの区切りです。
for i in range(0,len(s.parts)-1):
pnts = []
pnts = mapped[s.parts[i]:s.parts[i+1]]
crv = pm.curve(p=pnts,d=1)
crvs.append(crv)
crv = pm.curve(p=mapped[s.parts[-1]:],d=1)
crvs.append(crv)
pm.parent(crvs,grp)
g = grp.getParent()
pm.select(grp,r=1)
pm.rotate(g, [-90.0,0,0]) # MayaのY-Upに合わせて全体を回転します。
pm.viewFit( pm.selected())
pm.refresh(suspend=False)
for c in pm.ls(cameras=1): # 地図の場合、巨大な図形となるので、カメラのクリッピングプレーンを調整します。
c.setFarClipPlane(1000000)
c.setNearClipPlane(1)
# ※コピペするときは、使う前にコメントを全部削除してください。
import sys
if 'terrain.import_shapefile' in sys.modules:
reload(terrain.import_shapefile)
else:
import terrain.import_shapefile
道路のデータを取り込んでみた状態
元データが大きいと、結構時間がかかります。時に数時間かかることもあります。
一見、フリーズしたように見えても放っておけばそのうち終わります。
それがMaya。
###Mayaの単位の話
Mayaの単位について知っておくといいと思います。
MayaはCADソフトなどに比べて内部精度が低いです。
そのため、原点から遠く離れた位置に図形を描画するのが苦手です。
GIS系のデータであるシェープファイルは、この "原点から遠く離れた位置" に座標を持つことが珍しくありません。
これをMayaのデフォルト単位であるcmに変換して取り込もうとすると、描画エラーになることがあります。
詳しいことはわかりませんが、"桁落ち"とかそういう類のエラーだと思われます。
DXF/DWGを取り込もうとして、なぜか図が出てこないようなときはこれかもしれません。
面倒を避けたいなら、1ユニット = 1cm ではなく、1ユニット = 1m に読み換えて作業するといいです。
取り込み後に、原点の近くにオブジェクトを移動させてしまえば、その後はスケールを修正しても大丈夫です。