SilF - Pseudo 3D Sketch Tool


SilFは、米澤@柴山研が修論のために作った擬似3Dスケッチツールです。
SilFの名前は、Silhouette Floatからつけました。輪郭線が3D空間に浮いているイメージです。


概要

SilFの扱うデータは、3Dベジェ曲線です。モデリングするデータには、『面』はありません。輪郭線となる3Dベジェ曲線を回転角度に応じて投影し、それを一般の2Dのベジェ曲線として描画しているだけです。回転角度がそんなに大きくない範囲でなら、これだけのデータでも十分立体的に見えます。

このようなものをモデリングするには、結局2Dのデバイスで3D空間に線を描くことが必要です。SilFでは、そのためのかなり特異なインタフェースがいくつかあります。それらを一応頭に入れておかないと、操作はちょっと難しいと思います。


オブジェクトについて

各オブジェクトは、次のようなデータを保持しています。

  1. 3Dベジェ曲線、線や塗りつぶしの色、線の太さ、塗りつぶすかどうかのフラグ
  2. はじめに描かれた角度(正面の方向)
  3. 一番最近投影された面

1がメインのデータで、2と3は編集のための補助的なデータです。
2は、そのオブジェクトが初めて描かれたときの視線がどの方向だったかを記録しています。その方向を、そのオブジェクトの正面と呼ぶ事にします。そのオブジェクトを後に編集するとき、正面に近い角度から編集した場合と、遠い角度から編集した場合とで起こることが異なるようになっています。なお、正面は後に明示的に変更する事もできます。
3は、初めて描かれた時に投影された3D面のデータを持っています。後にガイドに投影した場合は、その面のデータになります。(ガイドは後の文を参照。)明らかに、元の面上での変更と思われる編集操作では、変更された部分もこの面に投影されます。また、後でこの面のデータからガイドを設定することもできますので、既存のオブジェクトと同じ面に新しく描きたいというような場合に便利になります。

各オブジェクトは、一般の2Dのドローツールと同じように、塗られる順番で並べられており、その順番に描画されます。その順番は、一般の2Dツールと同じように変更が可能です。一般の3Dツールと異なり、データには面がないため、陰面消去は(少なくとも普通の方法では)不可能です。そのため、ユーザが自分で重ねる順番を判断し、設定する必要があります。


ガイドについて

ガイドは、描いた曲線を3D空間に浮かべる際に投影する面をユーザが操作できるように考えたものです。ガイドもオブジェクトと同じように3Dの面をもっています。面の種類は、平面と楕円体をサポートしています。ガイドを表示中に描かれたオブジェクトは、ガイドの面に投影されます。また、既存のオブジェクトをガイドに改めて投影する事も可能です。ガイドは、移動や拡大縮小、回転も可能です。


↑メガネを投影した面


インタフェース

インタフェースは、ペン入力が主になります。サンプルはほとんど家のマウス操作で作りましたので、マウスでも何とかなるとは思いますが、やはり画面に直接書けるタイプのペンタブレットがあると楽だと思います。

SilFで実際に編集するためのモードは2つしかありません。ペン入力モードと、移動変形モードです。

ペン入力モードでは、ストロークを書き始める点によって、新しいオブジェクトの生成か、既存のオブジェクトの修正かが判断されます。

●ペン入力モード-新しいオブジェクトの生成

ペンで描いたとおりのベジェ曲線が生成されますが、問題はそれがどの3D面に投影されるかです。その優先順位は次のようになっています。

  1. ガイドが表示されている場合は、ガイド面に投影
  2. ストロークの始点と終点が既存のオブジェクトの3Dベジェ曲線にヒットしている場合、その2点を通って、描いた時の視線との成す角が一番大きい平面に投影
  3. ストロークの始点か終点が既存のオブジェクトの3Dベジェ曲線にヒットしている場合、その点を通って、描いたときの視線に垂直な平面に投影
  4. それ以外なら、描いたビューの現在の原点を通って、視線に垂直な平面に投影

●ペン入力モード-既存のオブジェクトの修正

選択されたオブジェクトの3Dベジェ曲線の上から描きはじめると、修正操作になります。描くときの角度によって、結果が異なってきますのでご注意ください。

2Dデバイスで3D空間上に曲線を描きたい場合、一回描いただけでは、3D曲線を決定する事はできません。これを解決するには、いろいろなインタフェースが考えられますが、このSilFでは、はじめに描いた後に修正を加えることによって、求める3D曲線に仕上げていくようなインタフェースを採用しました。いろいろな角度から見た形状を次々に与えれば、3D曲線を決定することが出来るわけです。

この操作法の場合、はじめに描いた後に加える他の角度からの修正では、はじめに描いた時の角度からの見た目は変更しない方がいいと考えられます。修正するたびに変化していたのではきりがなくなってしまいます。はじめに描いた角度から遠い場合には、はじめの角度から見て奥行き方向のみに曲線の変更を行えば、この条件を満たす事が出来るわけです。

編集対象のオブジェクトには、前述のとおり、正面の方向(初めて描かれた方向)が保存されています。この方向は、3Dベジェ曲線の端点に描画される短い直線によって、視覚的に確認できます。

もし正面に近い角度からあらためて修正しようとした場合には、普通に修正したいということを示すことになります。この場合には、新しいオブジェクト生成時の生成パターンに近い形でベジェ曲線が変更されます。

もしある程度正面とは違う角度から修正しようとした場合、正面からの見た目を保存したままで、曲線を変更したい事を示すことになります。この場合、正面から見て奥行き方向のみに曲線は変更されます。

  
正面からの修正例

    
他の角度からの編集例:正面からの見た目は変更しないように修正されているのが分かる(右図)

☆正面からの修正

正面からの修正では、修正する部分がどこなのかを決定する為に、元の曲線とストロークが成す角度を使います。それに注意して編集してください。

  

  

修正部分をどの3D面に投影するかは、新しいオブジェクトを生成するときと似ています。

  1. ガイドが表示されている場合は、ガイド面に投影
  2. ストロークの始点と終点が既存のオブジェクトの3Dベジェ曲線にヒットしている場合(修正対象のオブジェクトを含む)、その2点が、オブジェクトが保存している面(オブジェクトの項目参照)上の点なのかどうかを調べ、もしそうであればその面上に投影。もしそうでなければ、2点を通って描いた時の視線との成す角が一番大きい平面に投影
  3. それ以外(始点のみが修正対象のオブジェクトにヒットしている場合)、始点がオブジェクトの保存している面上の点なのかどうかを調べ、もしそうであればその面上に投影。そうでなければその点を通って視線に垂直な平面に投影

☆他の角度からの修正

前に説明したとおり、正面以外の角度から修正する場合、正面からの見た目を崩さないように正面から見て奥行き方向に変更されるわけですが、そのような変更が不可能なストロークを描く事も可能です。そのような場合は無視され、何も起こりませんのでご注意ください。

  

  

    

尚、この修正はガイドの表示状態には影響しません

☆スムージング

選択したオブジェクトの3Dベジェ曲線をなぞるようにすると、その付近がスムージングされます。これは、描く角度とは関係しません

●移動変形モード

オブジェクトを選択すると、その回りにハンドルが表示されます。赤い点をドラッグすると、リサイズします。青い点をドラッグすると、回転します。ハンドル内をドラッグすると、移動します。移動とリサイズでは、ツールバーのボタンによって、編集方向の制約をかけることができます。

ガイドを表示中の場合は、ガイドも同様に編集できます。中央の点をドラッグすると、高さを変えます。ガイドの四角い部分の中をドラッグすると移動します。リサイズ、回転は、面の方向を変えないように変化します。ガイドの向く方向を変えるには、ガイドの四角い部分をダブルクリックすると、現在の視線の方向に向きます。

●ガイドを用いた操作

ガイドを表示するには、ガイド表示ボタンをクリックします。ガイドの表示中は、ペン入力モードで描いたストロークの配置先が、ガイドの面上になります。(ペン入力モード参照) ガイドは、移動変形モードのときに自由に移動変形できます。(移動変形モード参照)

その他に、ガイドを用いた次のような操作が可能です。

ガイドをオブジェクトから設定

前述のように、オブジェクトは最後に投影された面を保存しています。その面をガイドの面として設定する機能です。これにより、既存のオブジェクトと同じ面上に描くことが可能となります。対象となるオブジェクトは、選択状態のものになります。複数選択されていて、共通する面がない場合には、無視されます。

ガイドにオブジェクトを投影

選択されたオブジェクトを、現在アクティブなビューの視線から、ガイドの面上に投影する機能です。

ガイド→ガイドをこちらに回転

ガイドを現在アクティブなビューから見て正面に来るように移動、回転させます。

●線の太さ、色、塗りつぶしの設定

対応するオブジェクトを選択し、パレットバーを操作することにより設定できます。

色のついている各ボタンをクリックして色を変更すると、選択されているオブジェクトの色が変わります。線の太さも同様です。「内部」のボタンをチェック状態にすると、ベジェ曲線の内部が塗りつぶされます。

●その他の操作

視線回転モード

ドラッグで視線を回転します。右ドラッグに設定することもできます。

視点移動モード

ドラッグで視点を移動します。右ドラッグに設定することもできます。

ズームモード

ドラッグでズームします。右ドラッグに設定することもできます。

すべて描画モード

そのビューで、ベジェ曲線内部も塗りつぶします。

稜線描画モード

そのビューで、ベジェ曲線のみ描画します。

オブジェクトの正面に視線設定

そのビューで、選択したオブジェクトの正面に移動します。複数選択されていた場合は、それらの中心付近に視点を移動します。

視線角度初期化

そのビューで、現在の視点、倍率を維持したまま視線角度を0に戻します。

すべて初期化

そのビューで、視点、視線、倍率を初期値に戻します。

表示→分割

ビューを分割します。いろいろな視点からの見た目を確認できます。

オブジェクト→重なり→各コマンド

オブジェクトの重なる順番を変更します。

オブジェクト→変形→各反転コマンド

オブジェクトをそれぞれの方向に反転します。

オブジェクト→グループ→グループ化

選択したオブジェクトをグループ化します。グループ化すると、グループ内のオブジェクト全てが一度に選択されるようになります。

オブジェクト→グループ→グループ解除

選択したグループを解除します。複合オブジェクトの解除にも使います。

オブジェクト→グループ→複合オブジェクト

選択したオブジェクト(グループは不可)を複合オブジェクトにします。複合オブジェクトとは、特殊なグループで、グループ内のレンダリングされる順番が変更され、複合オブジェクトにしたオブジェクト群の一番外側にだけ輪郭が表示されるようになります。解除するには、グループ解除を選択します。

  

レンダリングのアルゴリズムは単純で、グループ内のオブジェクトの輪郭のみを先に描き、その後中を塗りつぶします。これにより、一番外側の輪郭以外は内部が塗りつぶされた時に一緒に塗りつぶされて見えなくなります。この方法ですと線の太さが半分になってしまう為、始めに輪郭を描く時に無理矢理太さを倍にして描いています。そのため、オブジェクトが少し外側にふくらんだ感じになります。

これをうまく使うと、丸い3D形状をうまくあらわすことができます。下は、人の顔に適用した例です。人の顔の3D形状は複雑で、回転角度によって輪郭線は微妙に変化します。回転角度に応じた輪郭線を描いておいてそれらを複合オブジェクトにすれば、その様な輪郭線の変化を表現できます。

なお、色の違うオブジェクトや中身が塗られていないオブジェクト同士でも複合オブジェクトにできます。色が違っても、上の描画アルゴリズムは全く変わりませんので、一番外側の輪郭のみが描画されます。中身が塗られていないオブジェクトでは塗られている場合と異なり、中身が塗られているオブジェクトが内部を塗りつぶされる時に線が描かれます。よって、一番外側の輪郭でなくても線が描画されます。

オブジェクト→正面の変更

選択されているオブジェクトの正面を、現在アクティブなビューの視線方向に変更します。

 


エクスポート機能

SilFで描いた絵は、他形式の(2Dの)ファイルにエクスポートできます。ビューを分割しておけば、一つのビューの角度から他のビューの角度まで、連続に変化する画像を一気に出力できます。

対応している形式は次のものがあります。

BMP (Windows DIB)

普通の24bitのビットマップファイルです。アンチエリアシングを使えば、滑らかな画像も主力できます。

EMF (Enhanced Meta File)

Windowsの描画手順をそのまま保存したようなファイルです。ベクター画像ですので、一般的にBMPよりはファイルサイズがかなり小さくなります。MSOfficeに普通に読み込むことが可能です。座標が整数で書き込まれる関係上、小さい画像を後でOfficeで拡大すると、誤差が大きくなりますので、少し大きめに保存しておいた方がいいようです。

EPS (Encapsulated Postscript)

グラフィックス交換を目的に設計された、PSの変種です。Adobe IllustratorなどのEPSファイルをサポートしているグラフィックスソフトに読み込んだり、Texに貼り付けたりできます。

AI (Adobe Illustrator)

Adobe Illustrator用のベクター形式のファイルです。他にも多くのドローソフトがサポートしています。グループ構造も保持されます。

AI For Flash

FlashMXに読み込もうとしたところ、FlashMXのバグ?(あるいは設定のやり方がまずい?)せいで、閉じていないパスを読み込むときにおかしな結果になります。この形式を選択すれば、閉じていないパスをうまく処理するので、正確にFlashに読み込むことが可能です。グループ構造は無駄な容量増加を防ぐ為無視されます。

エクスポートするには、ファイル→エクスポートを選択します。


↑エクスポート設定ダイアログ

保存先のところで、保存先のフォルダとファイル名を設定します。連続出力する場合、ファイル名は、設定したものに”_番号”をつけたものになります。その後に、自動的に拡張子がつきます。

形式のところで、エクスポートする形式を選択します。

画像数のところで、連続出力する場合の画像数を指定します。連続出力しない場合には、単数のボタンをチェックしてください。ビューを分割しておかないと、連続出力はできませんので注意してください。

ベースサイズのところは、エクスポートする画像のサイズを示します。実際に出力される画像の大きさは、これに拡大率をかけたものになります。BMPファイル以外では、自動サイズ調整が使用できます。これにチェックしておくと、画像サイズはオブジェクトがちょうど入るサイズに調整されます。BMPファイル以外のベクター形式で自動サイズ調整をしないでサイズ指定をすると、バウンディングボックスをその設定のサイズに合わすようになっています。EMFの場合は正確に読み込むソフトならその画像サイズでクリッピングされますが、されないソフトもあるかもしれません。EPSやAIの場合、他のソフトに読み込むと設定されたサイズ外の部分も見えてしまうのが普通です。これの対応としてマスクをかけることが考えれられますが、今の所はやっていません。

拡大率は、現在ビューで表示されている状態からどれ位拡大するかを示します。ビットマップファイルの場合、ベースサイズにこの値をかけたものが、実際に出力されるサイズとなります。

アンチエイリアスは、ビットマップファイルのときのみ有効です。これを有効にすると、画像のギザギザが滑らかになります。アルゴリズムとしては、単純に品質倍の大きさのビットマップに描画してから、それを綺麗に縮小するという、かなりいい加減な事をしています。つまり、品質の2乗倍の時間とメモリを食うことになりますので、あまり品質の値を大きくしすぎないよう注意してください。

ビュー指定のところで、出力画像の視線角度、視点や倍率を指定します。連続出力したい場合は、ビューを分割し、希望の角度に設定しておいてください。


操作のコツ(?)

奥行き方向の変形の部分は、結構ややこしい事をやっているのでまだバグが残っている可能性はあります。ちょっと操作しにくいですが、ご了承ください。

●奥行き方向の変形が難しい

なるべく、角度をつけて、真横から見るくらいの感じで変形した方がやりやすいです。

●奥行き方向の変形をしたら、線がガタガタになった

その部分をなぞるようにすれば、スムージングできます。もしだめなら、視線を正面に戻し、その部分を書き直してしまうと綺麗になります。

●奥行き方向の変形をしようとしても、受け付けない

範囲外の部分までストロークを描いていませんか?もしそうでないなら、編集対象のオブジェクトの3Dベジェ曲線に細かい凸凹がありませんか?それによって、範囲外と判定されている可能性があります。その部分を綺麗にならしてみましょう。上手くできなければ、他の角度から試してみたり、少しずつ変形するようにすると上手くいきます。


by K.Yonezawa