チュートリアル データは、[Help] メニュー → [Download Tutorials and Examples…] を選択し、[CityEngine Tutorial] からダウンロードできます。
Python をベースにしたエクスポート機能を使用して CGA レポート変数を使用する方法を学習します。島の未来都市のシーンを使用して、シーン内に配置された散在しているインスタンスの情報をレポートにまとめ、シンプルなテキスト ファイルにインスタンス マップを生成します。このテキスト ファイルには、分散された建物インスタンスを任意のフォローアップ アプリケーションに、読み込むためのデータが含まれています。
すべてのインスタンスに対し、次の値を出力します。
これらを以下の形式で書きます。
nr | asset | xpos | xrot | xscale |
---|---|---|---|---|
0 | scifi_building_9.obj | -529.4803009 | 0 | 1.051229466 |
1 | scifi_building_17.obj | 236.6141357 | 0 | 0.933861537 |
2 | scifi_building_5.obj | 499.4240112 | 0 | 1.256899709 |
このチュートリアルは、3 つのパートで構成されています。
このチュートリアルでは、CGA 言語と Python スクリプトの基本知識が必要です。詳細は、スクリプトベースのエクスポートを確認ください。
演習 |
---|
・Part 1: インスタンス建物の情報をレポート |
・Part 2: レポートをエクスポートするためのスクリプト作成 |
・Part 3: 追加のアセット情報のレポートとエクスポート |
Part 1 ではまず、レポート用に使用する外部 CGA ファイルを準備します。
レポート用の汎用ルールを作成するには、以下の手順に従ってください。
次に、レポートルールを構築します。
InstanceReport(asset) -->
report("asset", asset)
report("xscale", scope.sx/assetInfo(asset, "sx"))
report("yscale", scope.sy/assetInfo(asset, "sy"))
report("zscale", scope.sz/assetInfo(asset, "sz"))
report("xrot", convert(x, scope, world, orient, 0,0,0))
report("yrot", convert(y, scope, world, orient, 0,0,0))
report("zrot", convert(z, scope, world, orient, 0,0,0))
report("xpos", convert(x, scope, world, pos, scope.sx/2,0,scope.sz/2))
report("ypos", convert(y, scope, world, pos, scope.sx/2,0,scope.sz/2))
report("zpos", convert(z, scope, world, pos, scope.sx/2,0,scope.sz/2))
InstanceReport(asset) -->
## report instance ID
report("asset", asset)
## report scale values relative to asset
report("xscale", scope.sx/assetInfo(asset, "sx"))
report("yscale", scope.sy/assetInfo(asset, "sy"))
report("zscale", scope.sz/assetInfo(asset, "sz"))
## report rotation in world coords
report("xrot", convert(x, scope, world, orient, 0,0,0))
report("yrot", convert(y, scope, world, orient, 0,0,0))
report("zrot", convert(z, scope, world, orient, 0,0,0))
## report position in world coords
report("xpos", convert(x, scope, world, pos, scope.sx/2,0,scope.sz/2))
report("ypos", convert(y, scope, world, pos, scope.sx/2,0,scope.sz/2))
report("zpos", convert(z, scope, world, pos, scope.sx/2,0,scope.sz/2))
NIL
次に、ルール ファイルを開き、準備したレポート ルールを使用します。
import instanceReporting:"instanceReporting.cga"
Building(asset) -->
s('1,0,'1)
i(asset) Asset.
instanceReporting.InstanceReport(asset)
ここでは、次に Python スクリプト ベースのエクスポートを使用して、準備したレポート データをエクスポートします。そのためには、Python スクリプトを作成する必要があります。詳細については、スクリプトベースのエクスポートを確認ください。
最初に、Python モジュールを作成します。
次に、レポート変数にアクセスします。
model.getReports()['asset']
if(model.getReports().has_key('asset')):
l = len(model.getReports()['asset'])
for i in range(0,l):
print model.getReports()
レポートデータの配列を Python コンソールに表示するには、次のようにします。
{'zpos': [-362.6108093261719], 'yrot': [-69.42008209228516], 'asset': ...
{'zpos': [-362.6108093261719], 'yrot': [-69.42008209228516], 'asset': ...
{'zpos': [-412.1033630371094], 'yrot': [165.30718994140625], 'asset': ...
processInstance () 関数を追加し、レポート値を処理して収集します。また、データを収集しインスタンスの数を追跡するための 2 つのグローバル関数 (finishModel 関数外で) を追加します。
# グローバル変数
gInstanceData = "" # 書き出される全データを収集するグローバル変数 (文字列)
gInstanceCount = 0 # 全インスタンスに番号を振るグローバル変数 (カウント)
finishModel() 関数を次のスニペットに更新します。
# 生成後の各初期シェープに対して呼び出し
def finishModel(exportContextOID, initialShapeOID, modelOID):
global gInstanceData, gInstanceCount
model = Model(modelOID)
if(model.getReports().has_key('asset')): # レポート データが存在する場合に t3d エントリのみ書き出し
# モデルに対して複数のアセットが存在する場合があるのでループを使用する
l = len(model.getReports()['asset'])
for i in range(0,l):
instanceData = processInstance(model.getReports(),gInstanceCount, i-1)
gInstanceData = gInstanceData+instanceData
gInstanceCount = gInstanceCount+1
report 変数をタブ区切りの文字列で返す processInstance() 関数を追加します。
# インスタンス情報をタブ区切り文字列で収集
def processInstance(reports, count, index):
## asset 文字列からパスを削除
asset = reports['asset'][index]
asset = asset.rpartition("/")[2]
## インスタンス マップ用の文字列を用意
text = "%d\t" % count;
text += "%s\t" % asset;
text += "%.3f\t%.3f\t%.3f\t" % (reports['xpos'][index],reports['ypos'][index], reports['zpos'][index])
text += "%.3f\t%.3f\t%.3f\t" % (reports['xrot'][index],reports['yrot'][index], reports['zrot'][index])
text += "%.3f\t%.3f\t%.3f\n" % (reports['xscale'][index], reports['yscale'][index], reports['zscale'][index])
return text
finishExport() 関数を追加します。この関数は、すべてのシェープの生成が完了した後に呼び出されます。インスタンス マップを含むテキスト ファイルのファイル名を定義し、writeFile() 関数を呼び出します。
# すべての初期シェープが生成された後で呼び出される。
def finishExport(exportContextOID):
global gInstanceData, gInstanceCount
## 出力ファイルのパス
file = ce.toFSPath("models")+"/instanceMap.txt"
## 収集されたデータをファイルに書き出し
writeFile(file, gInstanceData)
print str(gInstanceCount)+"instances written to "+file +"\n"
writeFile() 関数を追加し、ヘッダー情報を追加して収集したレポート文字列をディスクに書き込みます。その後、exportInstances.py スクリプトを保存します。
# データ (ヘッダーと内容) を結合し、ファイルに書き出し
def writeFile(file, content):
## ヘッダー文字列を準備
head = "nr\tasset\txpos\typos\tzpos\txrot\tyrot\tzrot\txscale\tyscale\tzscale\n"
## ヘッダーと内容を結合
content = head + content
## データをファイルに書き出し
report = open(file, "w")
report.write(content)
report.close()
完成したスクリプトを実行し、エクスポート ファイルを作成します。
タブ区切りのテキストファイルに書く代わりに、任意の方法でレポート データを処理することができます。 例えば、インスタンスを作成する Maya 用の Mel スクリプトを書く、データベースに位置情報を書き込む、または独自の ASCII 形式で書くなどがあります。
レポート ルールを使用することで、CGA ルール セットにレポートおよびエクスポート用の追加インスタンス要素を拡張することができます。これにより、詳細なデータの報告とエクスポートが可能になります。
reportInstances_02.cej シーンと instance_city_02.cga ルールを開きます。
instance_city_02.cga のルールで、Bridge ルールの一番下に instanceReport ルールを追加して、橋のアセットのインスタンス情報を instanceMap.txt ファイルにエクスポートします。 以前の instanceMap.txt ファイルが上書きされ、新しいファイルには橋のアセットのインスタンスも含まれています。reportInstances_03.cej シーンと instance_city_03.cga ルールを開いて、最終ルールが割り当てられたシェープを確認します。
Bridge -->
s(1,8,scope.sz+3.2) center(xz)
i(bridge_asset)
s(calcHeight2(scope.sx),calcHeight2(scope.sy),'1)
Bridge.
instanceReporting.InstanceReport(bridge_asset)
このチュートリアルでは、次のことを学びました。
・ インスタンス化されたアセットの情報をレポートする方法
・ レポートをテキストファイルにエクスポートできるスクリプトを作成する方法
・ スクリプトベースのエクスポーターを通じてエクスポートスクリプトを実行する方法
CityEngineの学習を続けるには、CityEngine チュートリアル カタログをご覧ください。