先日のバージョンはNURBSカーブをベジェ化して表示したまでだったので、次はサーフェスもやってみます。
カーブができていれば簡単で、パラメータUに関してベジェ化を行い、その結果をVに関してベジェ化することでBスプラインサーフェスはベジェサーフェスに変換できます。

ベジェ化部分を共用したいので、IGESパーサのスプラインを直接読むのではなくて一時的に別の構造を経由するようにしておきました。サーフェスでは同じノットベクトルで複数のスプラインを処理するので、その辺りができるようにしておきます。

さてサーフェスが表示できるようなったんですが、カーブならともかくサーフェスを2D表示してもちっとも面白くありませんでした。そこで無理矢理3D表示にしてしまおうと思います。本来は webgl を使うべきですが、Lion にアップデートしたら Chrome の webgl がうまく動かなくなってしまったので、今回は svg で 3D に挑戦してみます。

path エレメントを作る直前で、座標変換するようにしましょう。マトリックス操作は一から作ると大変なので、webgl でお世話になっている glMatrix ライブラリを使います。これ非常に簡単で良いです。

なかなかいい感じになってきました。動かすのはこちらから
IGES to SVG converter (firefox5, chrome12, safari5.1 で動作確認)

iges_ss1.jpg

今時の3Dビューワは画面のドラッグで視点操作ができないといけないので、カメラ制御用のオブジェクトを作りました。glMatrix の lookat 関数には GLU と同じように視点・注視点・アップベクタを渡せますので、これらを操作するような rotate, translate, dolly を作っておきます。

視点を操作したら、modelview 行列を更新します。今回は平行投影を使いますので projection はいりません。なぜか?それは svg で自力でニアクリップをするのが大変そうだから、です(実際のソースではパースも試したので identity で projection をかけてます)。

var modelView = mat4.create();
mat4.identity(modelView);
mat4.lookAt(eyeVec, refVec, upVec, modelView);

この modelView を頂点ごとにかけてやれば OK です。今回はさらに手抜きして、ビューポート変換を svg の transform でごまかして、頂点変換でスケールだけすることにします。svg の変換でもスケーリングは可能ですが、線の太さも変わってしまいます。線幅のスケーリングを回避する vector-effect: non-scaling-stroke というプロパティもあるんですが、chrome では対応しているものの firefox はまだみたいでした。

そんなわけで無事3D表示。ちょっと楽をして、制御点は座標変換してるんですが、その結果の2次元座標で svg path のスプライン描画しちゃってます。平行投影だとベジェがアフィン不変ということもあり、面白いですね。

描画の度にベジェ変換しているのでさぞ遅いだろうと思いましたが、結構いけるみたいです。chrome, safari, firefox では余裕でした。最近のjs環境すごいですね〜。絵が出せて楽しくなってきたので、次はちょっと効率を良くしてみます。