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} と設定するだけです。