マリオネット・スクリプト解説講座

新着記事第59回「スクリプトでリソースを管理する」

FundamentalsArchitectLandmarkSpotlightDesigner

今回はスクリプトを使用したリソースの管理について解説します。

Vectorworksのデータではシンボルをはじめとして、テクスチャやワークシート、オブジェクトスタイルなど多くのリソースが使用されており、お客様からもリソースをうまく管理したいというお声を多く頂戴しています。

スクリプトを活用した作業の効率化を考えたときに、意外と難しいのがこのリソースの管理です。リソースを管理するためのAPIとしてBuildResourceListという関数が用意されていますが、イマイチ使い方がわからないという方も多いのではないでしょうか。

今回はこのBuildResourceList関数を使用したリソースリストの作成方法を解説します。

59-1. BuildResourceList

BuildResourceListは指定した種類のリソースリストを作成してリソースリストの番号を返します。

BuildResourceListの引数(パラメータ)と戻り値は次のとおりです。

パラメータ

type:リソースリストに入れるリソースの種類の番号

folderIndex:フォルダの番号

subFolderName:folderIndexによって指定されるフォルダ内のサブフォルダの名前

戻り値

listID:リソースリストの番号

numItems:リソースリスト内のリソースの数

typeパラメータで指定するリソースの種類の番号は、Vectorworksでのオブジェクトの種類ごとに定められた整数値です。

四角形は3、レイヤは31など事前に割り振られています。設定されている整数値はスクリプトリファレンス等で確認できます。リソースとして扱うのはシンボル定義の16や、テクスチャ定義の97となりますので、この辺りを押さえておきましょう。

folderIndexで指定するフォルダの番号も、Vectorworksで事前に定められた番号となります。ここでのフォルダとはVectorworksアプリのインストールフォルダ以下のLibrariesフォルダやPlug-Insフォルダ等を指します。

基本的にはLibrariesフォルダ以下のリソースを含む.vwxファイルが格納されているフォルダの番号を指定することになります。アクティブなドキュメントからリソースを探す場合は0番を指定します。こちらもスクリプトリファレンスからフォルダ番号を確認することができます。

subFolderNameはその名の通りサブフォルダにアクセスしますが、folderIndexフォルダ(サブフォルダ内も含む)にあるすべてのファイルからリソースを取得するには、空文字列を指定します。

戻り値のlistIDで取得するリソースリストの番号は、作成したリソースリストにアクセスするための識別番号です。実行のたびにランダムに番号が振られますので、番号の数字の並びに意味はありません。

この識別番号はあとでリソースリストから情報を引き出すのに使用しますので、実行中のプログラムの中で値が変わらないように注意してコーディングする必要があります。

アクティブドキュメントのシンボル定義のリスト

listID, numItems = vs.BuildResourceList(16, 0, '')

ライブラリに用意されたマテリアルのリスト

listID, numItems = vs.BuildResourceList( 19, 345, '' )

ライブラリのサブフォルダに用意されたラインタイプのリスト

listID, numItems = vs.BuildResourceList( 96, 14, 'Attributes - Line Types' )

59-2. リソースの名前のリスト

リソースリストの番号を押さえていれば、リストからの情報の取得は簡単にできます。リソースの名前を取得するにはGetNameFromResourceListを使用します。

第1引数のlistIDはBuildResourceListで作成したリソースリストの番号です。

第2引数のindexには、名前を取得したいリソースはリソースリスト内の何個目のリソースなのか順番を指定します。順番は1番から始まります。

アクティブドキュメントに次のようにシンボル定義のリソースが登録されているとき、

シンボル定義のリソースリストから3番目の定義を取り出す場合は次のように記述します。

listID, numItems = vs.BuildResourceList(16, 0, '')
resname = vs.GetNameFromResourceList( listID, 3 )
vs.AlrtDialog( resname )

実行すると、3番目のシンボル定義の名前を取得できました。

numItemsによってリソースの総数が分かっているので、forループを使用して名前のリストを作成することができます。

reslist = []
listID, numItems = vs.BuildResourceList(16, 0, '')

for index in range( numItems ):
    resname = vs.GetNameFromResourceList( listID, index+1 )
    reslist.append( resname )

for resname in reslist:
    print( resname )

実行するとシンボル定義の名前のリストが作成できました。

※ printを使用して標準出力を確認する場合は環境設定で「スクリプトを開発者モードで実行」をONにしてください。

59-3. リソースの実体を取得する

リソースリストからリソースを取り出してオブジェクトとして操作または情報を取得する場合は、リソースの実体(ハンドル)を取得する必要があります。

アクティブなドキュメントにあるリソースはGetResourceFromListを使用してハンドルを取得することができます。GetNameFromResourceListと同じく、リソースリストの識別番号とリソースの番号を引数として渡します。

ハンドルのリストを取得する場合は次のように記述します。

objectlist = []
listID, numItems = vs.BuildResourceList(16, 0, '')
for index in range( numItems ):
    object = vs.GetResourceFromList( listID, index+1 )
    if object != 0:
        objectlist.append( object )

アクティブなドキュメントにないリソースの場合は、ハンドルが取得できずに0を返します。

ハンドルが取得できれば、オブジェクトの情報を取得することができます。リソースのハンドルを利用してシンボル定義の名前とオプションを取得してみます。

for obj in objectlist:
    symname = vs.GetName( obj )
    insertMode, breakMode, className = vs.GetSymbolOptionsN( symname )
    print( symname, insertMode, breakMode, className )

ライブラリのリソースなどアクティブファイルにないリソースは、アクティブファイルにインポートして実体化する必要があります。

リソースの取り込みにはImportResourceToCurrentFileを使用します。

ライブラリのマテリアルのリソースをアクティブドキュメントに取り込みます。

objectlist = []
listID, numItems = vs.BuildResourceList(19, 345, '')
for index in range( numItems ):
    obj = vs.GetResourceFromList( listID, index+1 )
    if obj != 0:
        objectlist.append( obj )
    else:
        obj = vs.ImportResourceToCurrentFile(listID, index)
        if obj != 0:
            objectlist.append( obj )

このスクリプトでマテリアルのリソースを取り込むことができますが取り込み時に重複するリソースが存在するとアラートが表示されます。

アラートを自動的に処理したい場合はImportResourceToCurrentFileではなく、ImportResToCurFileNを使用しましょう。ImportResToCurFileNでは、コールバック関数を定義することで重複アラートの処理を自動化することができます。

処理の方法は3種類です。

eImportResourceConflictResult_DoNotImport = 0
eImportResourceConflictResult_Replace = 1
eImportResourceConflictResult_Rename = 2

例えばコールバック関数で1を返すように設定すると、置き換えながら取り込みが実行されます。

def callback( resname ):
    return 1

objectlist = []
listID, numItems = vs.BuildResourceList(19, 345, '')
for index in range( numItems ):
    obj = vs.GetResourceFromList( listID, index+1 )
    if obj != 0:
        objectlist.append( obj )
    else:
        obj = vs.ImportResToCurFileN(listID, index, callback)
        if obj != 0:
            objectlist.append( obj )

59-4. リソースのリネーム

最後に、作成したマテリアルのリソースリストを利用して、マテリアルのリソース名を変更してみます。

マテリアルの物性値から密度の値を参照して、名前の先頭に密度の値を付与してリネームします。

def callback( resname ):
    return 0

objectlist = []
listID, numItems = vs.BuildResourceList(19, 345, '')
for index in range( numItems ):
    obj = vs.GetResourceFromList( listID, index+1 )
    if obj != 0:
        objectlist.append( obj )
    else:
        obj = vs.ImportResToCurFileN(listID, index, callback)
        if obj != 0:
            objectlist.append( obj )

objectlist = list(dict.fromkeys(objectlist))    #重複の解消
for mtl in objectlist:
    density = vs.GetObjectVariableReal( mtl, 1590 )
    mtlname = vs.GetName( mtl )
    newname = f'{density}-{mtlname}'
    vs.SetName( mtl, newname )

リソースリネームされ物性値の値を名前に追加することができました。リソースブラウザでは名前順にソートされるため、密度が小さい/大きい順にマテリアルが並ぶことになります(画像は降順です)。

この機能を利用できる製品

Fundamentals

Vectorworks Fundamentals

2D/3D汎用作図機能に、プレゼンボード作成機能や図面と連動できる表計算機能など、数多くの基本作図機能に加え、高品質レンダリング&3Dビジュアライズ機能を搭載したVectorworksシリーズの基本製品
詳細情報 購入ページ

Architect

Vectorworks Architect

建築設計や内装、ディスプレイデザインに対応した先進的なBIM・インテリア設計支援機能、拡張機能、さらには豊富な建築向けのデータライブラリを搭載した建築/内装業界向け製品
詳細情報 購入ページ

Landmark

Vectorworks Landmark

地形モデルや多彩な植栽、灌水設備計画等に対応するランドスケープデザイン機能、さらには豊富な造園向けのデータライブラリを搭載した都市計画/造園業界向け製品
詳細情報 購入ページ

Spotlight

Vectorworks Spotlight

ステージプランニングやライティング計画に対応した先進的な舞台照明計画支援機能、さらには各種メーカー製のトラスや照明機材、音響機器等の豊富なデータライブラリを搭載したエンタテインメント業界向け製品
詳細情報 購入ページ

Designer

Vectorworks Design Suite

専門分野別(建築設計/ディスプレイデザイン、ランドスケープデザイン、ステージデザイン&スポットライトプランニング)の設計支援機能、拡張機能、さらには豊富なデータライブラリを搭載した最上位の製品
詳細情報 購入ページ