CUBITでAPREPROを使用
CUBIT内でAPREPROを使用するには、APREPROステートメントをCUBITコマンドの一部として波括弧「{}」で囲みます。コマンドに含まれるAPREPROステートメントは、CUBITコマンドが実行される前に評価されます。たとえばAPREPRO変数「my_x」に3を代入すると、次のコマンドは
brick x {my_x}
次のようになります。
brick x 3
CUBITがコマンドを実行する前にこのように展開されます。つまり、APREPROによってCUBITがパラメトリックモデリング機能を持つわけではありません。上の例で、後から「my_x」の値を5へ変更しても、すでに作成されたBrickのサイズが自動的に5へ変わることはありません。
APREPRO式は独立した行に記述することもできます。この場合、APREPROステートメントの前にCUBITのコメント文字「#」を付けることを推奨します。これによりCUBITは評価後の式をコメントとして扱うため、多くの場合、不要なエラーを防止できます。
次の例を考えます:
#{my_x = 3}
#{my_y = my_x + 2}
#{if(my_y < my_x)}
brick x {my_x} y {my_y}
#{else}
create cylinder radius {my_x} height {my_y}
#{endif}
最初の2行ではAPREPROステートメントだけが実行され、変数「my_x」と「my_y」に値が代入されます。APREPROで評価された後、この2行は次の形でCUBITへ渡されます。
#3
#5
コメント文字を省略すると、CUBITは不正なコマンド構文として複数のエラーを出します。しかし、これらの行はコメント文字で始まるためCUBITでは無視されます。コメントには「#」の代わりに「$」も使用できます。
ループ
複数行の繰り返し処理は、 {loop(control)}, {endloop} コマンドで制御できます。詳細はAPREPROドキュメントの6.2.5節を参照してください。
指定回数に達する前にループを終了するには、 #{break} ステートメントを使用できます。 #{break} ステートメントが検出されるとループを終了し、その後のループ内ステートメントと残りの繰り返しは実行されません。
たとえば、次のコマンドでは3個のBrickを作成します:
#{_x = 1}
#{loop(10)}
brick x 1
#{if(_x == 2)}
#{break}
#{endif}
#{_x++}
pause
brick x 1
#{endloop}
#{break} ステートメントが実行されると、その後にある #{break} ステートメント以降の処理は、 #{endif}を含めてスキップされます。そのため、 #{break} ステートメントはループを終了するだけでなく、直前の #{if} ステートメントも、 #{endif} と同じように終了します。 #{break} ステートメントは、 #{if} ステートメントの外では使用しないでください。
ループは、 #{abortloop} ステートメントを使用して終了することもできます。 #{abortloop} は、ネストされたループを含むすべてのループを、ループ内容を実行せずに終了します。コマンドラインでループを手入力中に入力ミスをした場合に便利です。通常どおりループを閉じて多数のエラーを伴う実行を待つ代わりに、実行もエラーも発生させず直ちにループを終了できます。ただし、 #{abortloop} ステートメントはループブロック内でのみ有効で、ループ外ではエラーになります。
ループを作成すると、APREPROは対応する #{endloop} に到達するまで、コマンドラインへ入力されたすべての行を記録します。この間、CUBITへコマンドは渡されません。終了側の #{endloop} に到達すると、APREPROは記録した行をループカウンタで指定された回数だけ繰り返して展開し、そのコマンド一覧をCUBITへ送ります。終了側の #{endloop} を誤って省略すると、APREPROがループ用の行を記録し続けるため、CUBITがコマンドに反応しないように見えることがあります。この場合は、 #{abortloop} ステートメントを使って未完了のループを終了し、コマンドラインを通常の状態へ戻せます。
また、ループ内で「pause」コマンドを使用することは推奨しません。ループ全体を実行するために「resume」コマンドを繰り返し入力しなければならない場合があるためです。この状況では、 #{abortloop} を実行してもループは終了しません。すでにAPREPROによってループが展開され、CUBITは単にコマンド一覧を実行している状態だからです。
APREPRO変数の削除
CUBITでAPREPRO変数を削除する方法は2つあります。1つ目はAPREPROの「delete」関数を使用する方法です。delete関数には、次の例のように削除する変数名を引数として渡します:
#{my_var = 2}
...
#{delete('my_var')}
2つ目は「reset aprepro」コマンドを使用する方法です:
#{my_var = 2}
#{some_var = 3}
...
reset aprepro
これにより、すべてのAPREPRO変数が削除され、APREPROは初期状態にリセットされます。
その他の例
次の例では、いくつかの文字列関数の使用方法を示します。
#{t1 = "ATAN2"}{t2="(0,-1)"}
#{t3 = tolower(t1 // t2)}
... 変数t3は文字列 atan2(0,-1) と等しくなります。
#{execute(t3)}
...t3 = 3.141592654
結果は {atan2(0,-1)} を実行した場合と同じです。かなり人工的な例ですが、複数の関数がどのように動作するかを示しています。最初の例では、2つの文字列を連結して式を作り、その文字列を小文字へ変換した後、その文字列を実行しています。
次の例では、APREPROの基本的なマクロ機能を示すために rescan 関数を使用します。この例では、半径10、180度の円弧上に等間隔でVertexを作成します。マクロは5行で構成されます(ループ構文を除く2行は#で始まります。実際のジャーナルファイルでは継続行にはならず、それぞれ1本の長い行として記録されます)。
#{num = 0} {rad = 10} {nintv = 10} {nloop = nintv + 1}
#{line = 'Create Vertex {polarX(rad,(++num-1)*180/nintv)} {polarY(rad,(num-1)*180/nintv)}'}
#{loop(nloop)}
{rescan(line)}
#{endloop}
ループ構文により、 rescan 行を自動的に繰り返している点に注目してください。この例を11点ではなく101点の座標計算へ変更するには、{nintv=100} と設定するだけです。