チュートリアル データは、[Help] メニュー → [Download Tutorials and Examples…] を選択し、[CityEngine Tutorial] からダウンロードできます。
このチュートリアルは、主にモデルにハンドル機能を追加したい CGA ルール作成者向けです。ハンドルを設定すると、[Viewport] ウィンドウ内で CGA 属性を編集することができます。モデル編集を簡易化し、どの属性をコントロールできるかを視覚的に確認することができます。
演習 |
---|
・Part 1: 基本的なライン ハンドル |
・Part 2: 高度なライン ハンドル |
・Part 3: その他のハンドル タイプ |
ハンドルは CGA で使用される属性アノテーションによって生成され、動的な編集ツールを提供します。これにより、モデルの寸法や位置を [Viewport] ウィンドウ内で直接、精密に操作することができます。このセクションでは、まずライン ハンドルの作成から始めます。
#@Handle(shape=Cube)
attr height = 10
#@Handle(shape=Cube, axis=x, skin=sphere, color="#6666ff")
attr width = 10
#@Handle(shape=Cube, axis=z, skin=diameterArrow)
attr depth = 10
#@Handle(shape=ShapeForHandleOnly
axis=x
reference=origin
slip=inside
translate={0,0.5,0})
attr offsetX = 5
Lot -->
[ s(offsetX,height,1) ShapeForHandleOnly ] t(offsetX,0,0)
t(0,0,-depth/2) s(width,0,depth)
extrude(height)
Cube
Cube -->
color("#E5E6E7")
ShapeForHandleOnly --> NIL
キューブの高さを調節するハンドルを作成します。
@Handle(shape=Cube)
attr height = 10
これにより、キューブ モデルの高さを制御するハンドルが追加されます。ハンドルは CGA ルールのスコープに付与されます。この最初の例では、生成されるキューブ モデルのジオメトリーとスコープが一致するため、Cube ルールが選ばれています。
ハンドルはモデルの外側に配置されます。ビューを回転させるとハンドルも合わせて最適な位置に移動するので、モデルに隠れたりしません。
次にキューブの幅をコントロールするハンドルを作成します。
@Handle(shape=Cube, axis=x, skin=sphere, color="#6666ffff")
attr width = 10
これは、同じ Cube という名前のルールに別のハンドルを追加し、位置や外観をカスタマイズするための追加パラメーターを使用します。
次に、キューブの奥行きをコントロールするハンドルを作成します。
@Handle(shape=Cube, axis=z, skin=diameterArrow)
attr depth = 10
再び、axis パラメーターを設定して、ハンドルが配置されるスコープ軸を指定します。モデルの depth 属性は、width や height 属性とは異なる動作をします。この属性はキューブの中心を基準にして奥行きをスケーリングします。この動作に対応するために、skin=diameterArrow パラメーターを使用します。これにより、異なるドラッグ動作を持つハンドルが作成され、奥行きを変更するために使用できる 2 つの青い矢印が表示されます。
最後のパラメーターである offsetX には、視点が変化しても動かないハンドルを作成します。
@Handle(shape=ShapeForHandleOnly, axis=x, reference=origin, slip=inside)
attr offsetX = 5
Lot -->
[ s(offsetX,height,1) ShapeForHandleOnly ] t(offsetX,0,0)
t(0,0,-depth/2) s(width,0,depth)
extrude(height)
Cube
Cube -->
color("#E5E6E7")
ShapeForHandleOnly --> NIL
このハンドルは、ジオメトリーを生成しないこのハンドル専用に作成された空のプレースホルダー スコープの ShapeForHandleOnly に付加されています。
slip=inside パラメーターは、ハンドルがモデルの輪郭内に配置され、視点の変更によって動かないように指定します。通常、ハンドルは指定された軸方向において、スコープの 4 つの辺のいずれかに表示される可能性がありますが、reference=origin パラメーターを使用すると、ハンドルはスコープの原点に隣接する辺のみに表示されます。
@Handle(shape=ShapeForHandleOnly,
axis=x, reference=origin, slip=inside, translate={0,0.5,0})
attr offsetX = 5
translate = パラメーターは現在のスコープに合わせてハンドルを移動させます。引数 {0, 0.5 ,0} は、scope-y のサイズ (高さ) に対して 0.5 倍分、つまり上方向にハンドルを移動させます。
translate= パラメーターがない場合、offsetX ハンドルは床の位置 (左) にあり、translate= パラメーターを使用すると、ハンドルはキューブの中心 (右) に配置されます。最初の 3 つのハンドルはシルエットの外側にありますが、slip=inside パラメーターによって、このハンドルは常に見えないキューブのシルエット内に配置されます。ハンドルにマウスカーソルを重ねると、shape という名前のルールのスコープが青くハイライト表示されます。
より複雑な風車のモデルを使用してハンドルを設定します。
本チュートリアルの Part 1 では、立方形のシェープにハンドルを追加しました。視点が変わると、ハンドルはキューブの面と同じ平面にスナップされていました。同様の設定を円搭形の風車小屋オブジェクトに適用できます。
@Handle(shape=UnderRoof)
@Range(min=3, max=100)
attr height = 7
視点を回転させると、このハンドルはあまり効果的ではないことがわかります。視点が回転すると、UnderRoof スコープのコーナーの位置の間をジャンプします。スコープは建物よりも大きく、形状が異なるため、モデルとハンドルの関連付けを追跡することは困難です。
@Handle(shape=UnderRoof, reference=center, slip=screen)
@Range(min=3, max=100, restricted=false)
attr height = 7
reference = center パラメーターによってハンドルがスコープの中心に付与されます (詳細は、CGA リファレンスをご参照ください)。slip = パラメーターはハンドルがモデルの外側に移動する方向を定義します。今回の場合、slip=screen パラメーターによって、ハンドルはカメラの 2D スクリーンに平行に移動します。これによって作成されたハンドルはより明確かつスムーズに動きます。
画面の上部と下部に、風車の半径を制御する 2 つのハンドルを追加することができます。
@Handle(shape=UnderRoof, reference=radial, align=bottomLeft)
@Range(min=1.5, max=9)
attr bottomRadius = 2
@Handle(shape=UnderRoof, reference=radial, align=topLeft)
@Range(min=1.0, max=5.1)
attr topRadius = 1
モデルの周りで視点を回転させると、2 つのハンドルがモデルのジオメトリーに対して適切に動くことがわかります。reference=radial パラメーターは、円筒の半径を調整する位置にハンドルを配置します。align= パラメーターは、[Viewport] ウィンドウ内でハンドルの表示位置を指定するためのパラメーターです。align を使用することで、画面上で各ハンドルの位置を固定することができます。これを定義しない場合、bottomRadius ハンドルがモデルの上部に表示されてしまうことがあります。
多くのモデルでは、1つの属性が複数のパートに影響を与えます。この風車小屋の例では、bladeLength 属性が風車の 4枚の羽根の長さを変更します。CityEngine はそのようなハンドルを連結して、各属性に対して 単一のチェーン ハンドルとして表示します。
@Handle(shape=Blade, axis=x, reference=origin)
attr bladeLength = height * 0.6
視点の方向によって、異なるハンドル チェーンが表示されることがあります。この例では、風車の羽根に対して 2 つのハンドルからなる 1 つのチェーンとして表示しています。
@Handle(shape=Blade, axis=x, reference=origin, repeat=none)
attr bladeLength = height * 0.6
windowScale 属性は少し複雑ですが、ドアと窓のサイズを操作できます。
windoor ルールは単一のルールで窓とドアの両方を作成します。
@Handle(shape=Windoor, axis=y)
@Range(min=0.1, max=1.5)
attr windowScale = 1
height 属性を編集すると、窓の数が増減します。
windowScale 属性に関するもう一つの観点は、これは縮尺の値であり、窓のサイズではないということです。さらに、各窓やドアには異なるサイズのスコープが関連付けられています。CityEngine は繰り返す要素の上にチェーン ハンドルを配置し、各スコープに合わせて各ハンドルの長さをスケーリングします。このようなライン ハンドルをドラッグすると(ハンドルの長さとは異なる値で)、実際の長さが括弧内に表示されます。
このチュートリアルの最後のワークフローでは、カラー、トグル、回転ハンドル、およびスコープの削除によるハンドルの非表示にする方法について見ていきます。
なじみのない CGA コードを扱う際には、[Model Hierarchy] ウィンドウを使用して使用可能なスコープを確認すると便利です。
import leftArm : "limb.cga"
import rightArm : "limb.cga"
import leftLeg : "limb.cga"
import rightLeg : "limb.cga"
@Handle(type=linear, axis=x, reference=origin, translate={0, 0.5,0.5},shape=HeadHandle^1, skin=diameterArrow)
attr boneSize = 0.16
@Handle(type=linear, shape=Mass, align=left)
attr height = 1.85
@Color
attr color = "#888888"
attr showLimbHandles = false
Lot -->
t (-boneSize*2.15,0,0)
s (boneSize*4.3, 0, boneSize )
extrude(height)
Mass
Mass -->
split (y)
{
~4 : Body |
boneSize*2 : Head
}
Head -->
t (scope.sx/2-boneSize , 0, scope.sz/2-boneSize )
s (boneSize*2, boneSize*2, boneSize*2)
HeadHandle("sphere.obj")
HeadHandle(mesh) -->
i (mesh) X
# (…)
このチュートリアルの Part 1 と Part 2 では、ライン ハンドルを使用しました。これらのタイプに加えて、ハンドルは他の種類の属性も調整できます。次は、モデルの頭上に配置されるカラー ハンドルを追加します。
次に、前のセクションで確認した HeadHandle スコープにカラー ハンドルを追加します。
@Handle(type=color, shape=HeadHandle^1, axis=y, reference=center)
@Color
attr color = "#888888"
スコープは、そのルール名とルールが受け取るパラメーターの数によって識別されます。この場合、shape=HeadHandle^1 です。これまでの例では、パラメーターの数がゼロだったため、この識別子を省略することができました。color 属性は文字列であり、type=color パラメーターを使用することで、[Viewport] ウィンドウ内で編集可能になります。カラー、トグル、セレクター ハンドルは、ライン ハンドルとは異なる動作をします。たとえば、axis=y はハンドルが y (上方向) に移動できるようにし、reference=center はハンドルをスコープの中心点に付与します。
三角形の内側をクリックしてドラッグすると、色の彩度と明度が変化します。同じクリックを保持したまま大きな円の周囲をドラッグすると、色相が変化します。以前に選択した色は、ホイールの外側の小さな円に表示されます。
ルール内で関連するスコープの生成を制御することにより、ハンドルを非表示にすることができます。このモデルの各腕、および脚は、1 つのインポートされたルール インスタンスによって作成されています。それぞれのインポートされたインスタンスには、手足の位置を制御するための 3 つのパラメーターを持っています。しかし、モデルにこれらの 12 個のハンドルを追加すると、紛らわしくなります。そこで、これらのハンドルに、ブール属性 (showLimbHandles) が true の場合にのみ生成されるオプションのスコープを付与します。
@Handle(type=toggle, shape=HeadHandle^1, slip=screen, align=right)
attr showLimbHandles = false
トグル ハンドル タイプは Boolean 属性に対して提供され、四角形のスイッチとして表示されます。今回は、slip=screen と align=right を使用して、ハンドルを球状の頭部の右側に一貫した位置で配置します。
デフォルトでは、回転ハンドルは表示方向が変わっても動きません。ただし、横から見るとハンドルは見えなくなります。視点をモデルの周囲で回転させることで、より良いハンドルの操作が可能になることがあります。そうすることで、モデル上に配置されたすべてのハンドルと、それらの編集により影響を受ける属性を確認できます。ぜひ、ハンドルのさまざまな可能性と、ハンドルをモデルにどう適用できるかを探ってみてください。