今回はスクリプトのマニアックな内容です。VectorScriptのスクリプトの中でPythonのスクリプトを実行する方法をご紹介します。
VectorScriptのスクリプトの中でPythonのスクリプトを実行できることをご存知でしょうか。
VectorScriptはVectorworksに特化した言語ですので、Vectorworksで作図や操作を命令する場合には最適な言語です。一方でデータの処理やOSへのアクセスなど汎用性ではPythonに軍配が上がります。
いずれも一長一短ありますが、VectorScriptとPythonを組み合わせることで、それぞれの言語の長所を活かしたプログラムを作成することができます。
53-1. PythonExecute
PythonExecuteは、VectorScript(以下VS)の中でPythonのスクリプトを実行するための手続きです。Pythonのスクリプトを文字列で渡すことで、Pythonのスクリプトを実行することができます。
まずはお馴染みの「Hello, World!」をPythonで標準出力するVSスクリプトを作成します。
Procedure test; Var pythonstring : Dynarray of Char; Begin pythonstring := 'print("Hello, World!")'; PythonExecute( pythonstring ); End; Run( test );
上記のスクリプトを実行すると、VSの実行中にPythonのスクリプトが実行され、標準出力に「Hello, World!」が表示されます。
53-2. 複数行のPythonスクリプト
複数行のスクリプトを実行する場合は、PythonExecuteに渡す文字列自体を改行して記述します。例として、VSでは取得できない、OSの詳しい情報を拾うスクリプトを作成します。
Procedure test; Var pythonstring : Dynarray of Char; Begin pythonstring := ' import os import sys import platform print(platform.system()) print(os.name) print(sys.platform) print(platform.release()) print(platform.version()) print(platform.platform()) '; PythonExecute( pythonstring ); End; Run( test );
Pythonのインデントを意識する必要があるため、格好良く書くことは難しそうです。
macOSでの実行結果となります。intelチップのMacなのか、MシリーズのMacなのかを見分けることができます。
インデントが必要な場合は文字列の中に含める必要があります。また、VSの中のPythonの中でもvs.**から始まるVSの関数を使用することができます。
Procedure test; Var pythonstring : Dynarray of Char; Begin pythonstring := ' import vs import platform if "arm" in platform.platform(): vs.AlrtDialog( "MシリーズのMacです。" ) else: vs.AlrtDialog( "IntelのMacです。" ) '; PythonExecute( pythonstring ); End; Run( test );
53-3. 値の受け渡し
VSで使用している変数をPythonに渡して使用する方法を解説します。
53-3-1. 文字列に埋め込む
単純にPythonExecuteに渡す文字列に値を連結してしまう方法です。文字列の連結にはConcatを使用します。
VSで使用している2つの整数値について、Pyhtonでの最大公約数を求めてみます。
Procedure test; Var value1, value2 : Integer; pythonstring : Dynarray of Char; Begin value1 := 28; value2 := 42; pythonstring := Concat(' import vs import math value1_py =', Num2Str(0,value1),' value2_py =', Num2Str(0,value2),' gcd = math.gcd( value1_py, value2_py ) vs.AlrtDialog( f"最大公約数は:{gcd}" ) '); PythonExecute( pythonstring ); End; Run( test );
53-3-2. リポジトリを使う
起動中のVWアプリが確保しているメモリ領域(リポジトリ)にデータを保存する方法です。Rpstr_***で始まる名前の関数はリポジトリにアクセスするために用意されたものです。
-
- Rpstr_GetValueBool
- Rpstr_SetValueBool
- Rpstr_GetValueStr
- Rpstr_SetValueStr
など、値の型ごとに取得・保存の関数が用意されています。
Procedure test; Var value1, value2 : Integer; pythonstring : Dynarray of Char; Begin value1 := 28; value2 := 42; Rpstr_SetValueInt('value1_vs', value1); Rpstr_SetValueInt('value2_vs', value2); pythonstring := Concat(' import vs import math value1_py = vs.Rpstr_GetValueInt("value1_vs", 0) value2_py = vs.Rpstr_GetValueInt("value2_vs", 0) gcd = math.gcd( value1_py, value2_py ) vs.AlrtDialog( f"最大公約数は:{gcd}" ) '); PythonExecute( pythonstring ); End; Run( test );
PythonExecuteではデータの流れはVSからPythonへの一方通行を想定されていますが、リポジトリを使えば、Pythonの実行結果をVSで取得することができます。
Procedure test; Var value1, value2, value3 : Integer; pythonstring : Dynarray of Char; Begin value1 := 28; value2 := 42; Rpstr_SetValueInt('value1_vs', value1); Rpstr_SetValueInt('value2_vs', value2); pythonstring := Concat(' import vs import math value1_py = vs.Rpstr_GetValueInt("value1_vs", 0) value2_py = vs.Rpstr_GetValueInt("value2_vs", 0) gcd = math.gcd( value1_py, value2_py ) vs.Rpstr_SetValueInt("value3_vs", gcd) '); PythonExecute( pythonstring ); value3 := Rpstr_GetValueInt('value3_vs', 0); Message( value3 ); End; Run( test );
53-4. Macチップ判定の関数化
紹介した値の受け渡しの方法を使って、Macのチップ判定を関数化してみましょう。MacのチップがArmかどうかの判定(True/False)だけをPythonから取得して、その他はVS側で処理するようにします。
Procedure test; Function isArmMac : Boolean; Var pythonstring : Dynarray of Char; Begin pythonstring := ' import vs import platform vs.Rpstr_SetValueBool("isArmMac", "arm" in platform.platform()) '; PythonExecute( pythonstring ); isArmMac := Rpstr_GetValueBool('isArmMac', False); End; Begin if isArmMac then AlrtDialog( 'MシリーズのMacです。' ) else AlrtDialog( 'IntelのMacです。' ); End; Run( test );
53-5. 文字列置換
文字列の処理はPythonが得意な部分です。VSの文字列を渡して、Pythonで文字列の置換をする関数を作成します。
Procedure test; Var vsstring : String; Function ReplaceString( str,old,new : String ) : String; Var pythonstring : Dynarray of Char; Begin pythonstring := Concat(' s = "',str,'" s = s.replace( "',old,'", "',new,'" ) vs.Rpstr_SetValueStr( "ReplaceString", s ) '); PythonExecute( pythonstring ); ReplaceString := Rpstr_GetValueStr('ReplaceString', ''); End; Begin vsstring := '[aanda.co.jp](https://www.aanda.co.jp/)'; AlrtDialog( vsstring ); vsstring := ReplaceString( vsstring, 'aanda', 'vectorworks' ); AlrtDialog( vsstring ); End; Run( test );
VSのみで文字列置換をする場合には、PosやSubStringなどを駆使して複雑なコードを書く必要がありますが、Pythonだとreplaceの1行だけで済みます。
インデントやファイルパスなどいくつか注意すべき点はありますが、VSとPythonを組み合わせることで、確実にできることが増えます。「これはVectorScriptじゃないとできない、あれはPythonじゃないとできない」という課題も一挙に解決できる手段ですので、開発の実務でも頻繁に使用しています。VWにPythonが実装されて久しいですが、研究するほどに奥深さに気づくことができて楽しいですね。
この機能を利用できる製品
Vectorworks Fundamentals2D/3D汎用作図機能に、プレゼンボード作成機能や図面と連動できる表計算機能など、数多くの基本作図機能に加え、高品質レンダリング&3Dビジュアライズ機能を搭載したVectorworksシリーズの基本製品 |
|
Vectorworks Architect建築設計や内装、ディスプレイデザインに対応した先進的なBIM・インテリア設計支援機能、拡張機能、さらには豊富な建築向けのデータライブラリを搭載した建築/内装業界向け製品 |
|
Vectorworks Landmark地形モデルや多彩な植栽、灌水設備計画等に対応するランドスケープデザイン機能、さらには豊富な造園向けのデータライブラリを搭載した都市計画/造園業界向け製品 |
|
Vectorworks Spotlightステージプランニングやライティング計画に対応した先進的な舞台照明計画支援機能、さらには各種メーカー製のトラスや照明機材、音響機器等の豊富なデータライブラリを搭載したエンタテインメント業界向け製品 |
|
Vectorworks Design Suite専門分野別(建築設計/ディスプレイデザイン、ランドスケープデザイン、ステージデザイン&スポットライトプランニング)の設計支援機能、拡張機能、さらには豊富なデータライブラリを搭載した最上位の製品 |