« ○。 | トップページ | 2011以前でタブなスクリプトエディタ。 »

2011年2月25日 (金)

Add to クラスタの憂鬱。

連日スクリプト書いてます。


T = Selection(0).type;
if ( T == "polySubComponent" )    //    Currently only poly clusters supported.
{
    var oSub = Selection(0).SubComponent;
    var oObj = oSub.Parent3DObject;

    var oClusters = oObj.ActivePrimitive.Geometry.Clusters.Filter( "poly" );
    if ( oClusters.count == 0 )
    {
        Logmessage( "No fuckin' clusters found on this god damn object.", siWarning );
    }
    else
    {
        //    Get a cluster to add the selected polygons to.
        //    Actually the function only returns a fullname of the cluster, not cluster object,
        //    despite the name of the variable "oTargetCluster".

        var oTargetCluster = GetTargetCluster( oClusters );   
        if ( oTargetCluster )
        {
            var oUpdatedCluster = AddToCluster( oTargetCluster + "," + oSub )(0);
            // User will be prompted when overlaps unless preference is changed.
        }
    }
}

function GetTargetCluster( oClusters )
{
    var aClusterUIItems = new Array( );
    for ( var i=0; i<oClusters.count; i++ )    //    Build array for combo menu item
    {
        var oCluster = oClusters(i);
        var ClsMatName = GetClusterMatName( oCluster );    //    Get mat name for the cluster
        ClsAndClsMatMenuItemString = oCluster.name + "     ( " + ClsMatName + " ) ";
        aClusterUIItems.push( ClsAndClsMatMenuItemString );
        aClusterUIItems.push( oCluster.fullname );
    }

    //    Build PPG

    var oP = XSIFactory.CreateObject( "CustomProperty" );
    oP.name = "";
    var oParam, oL, oItem;   
    oParam = oP.AddParameter2( "sCluster", siString, aClusterUIItems[1] );
    oL = oP.PPGLayout;
    oItem = oL.AddEnumControl( "sCluster", aClusterUIItems, "Add To", siControlCombo );

    Inspect = InspectObj( oP, null, null, siModal, false);
    if ( !Inspect )
    {
        return oP.sCluster.value;
    }
    else
    {
        return null;
    }
}

//    Find cluster material & returns its name
function GetClusterMatName( oCluster )
{
    for ( var j=0; j<oCluster.LocalProperties.count; j++ )
    {
        if ( oCluster.LocalProperties(j).IsClassOf( siMaterialID ) )
        {
            var oMat =  oCluster.LocalProperties(j);
            break;
        }
    }
    if ( oMat )
    {
        return oMat.name;
    }
    else
    {
        return "** NO MAT **";
    }
}



何をするスクリプトかと言うと、現在選択中のポリゴンを既存のクラスタに追加するスクリプトです。 ポリゴンを選んで実行すると PPG が降臨し、そのオブジェクトに既に存在するポリゴンクラスタがドロップダウンメニューに羅列されます。このドロップダウンからクラスタを選んでOKを押すと、選択していたポリゴンがそのクラスタに追加されます。 クラスタにマテリアルがあった場合は、そのマテリアル名がカッコの中に表示されます(ここ重要)。主にマテリアル付きのクラスタに新たにポリゴンを追加するという操作を想定しています。

Addtocls

そんだけです。
基本的に、ポリゴンをクラスタに追加するだけ。

そんなもん、本当は XSI 標準のワークフローでやればいいわけですが。

でも俺は、あのやり方が嫌いなんです。憂鬱になります。


  1.ポリゴン選んで、
  2.Explorer で延々と掘り進んでクラスタを発掘し、
  3.Ctrl とか押しながらクラスタを選び、
  4.すごく押しやすくできている + ボタンを押す


Explorer をほじくっているあたりからストレスが湧いてきて、Ctrl 押すあたりで脳味噌が沸騰し、最後のボタンを押す工程でモニタを破壊します。 実に憂鬱です。

 なんだよっ この小せえボタンはっ
 インターフェースのいちばんはじっこに
 嫌がらせのように配置しやがってっ
ドルァ


だってこんなボタンですよ。

↑わかりにくいですか。クリックすると大きな画像が出ます。小さくてクリックしにくいけどな!

このプラスボタンの大きさや配置はかなり激怒ものですしExplorer をほじくってクラスタを見つける過程もけっこう苦痛です。 しかもクラスタにちゃんと名前を付けてなくて Polygon1 とかになってるとどのクラスタに入れていいのか判らずいちいち横の + アイコンをクリックして展開しマテリアルの名前などを調べてるうちにさらにモニタの破壊台数が増えます。憂鬱です。しかもそうやってマテリアルの名前を確認したらやはり名前付けをサボっていたために Material1 とかのままになっており結局迷うわけですがまあそういうときはこのスクリプトであらかじめ整理しておくしかないけどともかくこのワークフローは苦痛なのです憂鬱です。

だから、Explorer をほじくったり小さいボタンを押したりする代わりに、PPG が出てきてそこから追加先のクラスタを選べれば楽かな、と思ったわけですよ。 

実際使ってみたら、はははは、笑うくらい便利じゃないか。 さすが俺様。 自分用に書いたツールほど便利なものはない。ざまーみろ嘔吐デスク。お前の母ちゃん出臍。 この文脈において嘔吐デスクに暴言を吐く妥当性は微妙ですが。



最近クラスタマテリアルを大量に扱っているんですね。 モデリングを進めながら、識別用の仮マテリアルが付いたクラスタにポリゴンをどんどんぶち込んで行くんです。1オブジェクト内にたくさんパーツ、というかポリゴンのエリアがあるんですが、そのパーツごとにマテリアルが分かれてないとパッと見で識別ができず、モデリングが進めにくいのです。 よって、モデリングが全て済んでからクラスタにマテリアルを与えるのでは意味がなく、モデリングそのものを進めやすくするためにマテリアルを与えながらやっているのです。 この過程で上記のワークフローの煩雑さにキレてモニタが何個も破壊されたので、昨日とうとう書きました。全然難しくなかった。30分くらいで書けた。早く書けば良かった。どうしてくれるんだ嘔吐デスク。




スクリプティング的な要点は・・・・別に新しいことは何もしてないですね。クラスタの取得、クラスタマテリアルの取得。さほど難しくもなければ、全く画期的でもありません。

前半、ポリゴンを選択している状態をスタートに、芋づるをしてますね。

    var oSub = Selection(0).SubComponent;
    var oObj = oSub.Parent3DObject;
    var oClusters = oObj.ActivePrimitive.Geometry.Clusters.Filter( "poly" );


この辺。


1行目。 ポリゴンからサブコンポーネントを作ります。 サブコンポーネントって? 俺もよく分かってません。分かってないけど、クラスタ扱うには必須という感じ。まずは選んでいるポリゴン(やエッジやポイント)からサブコンポーネントというものを構築しないと、その次の芋づるに行かないと感じています。


2行目。 1行目でゲットしたサブコンポーネントに対し Parent3DObject プロパティを使って、親オブジェクト( X3DObject )を取得しています。 前にゲットしたものを使って新たなものをゲットする = 芋づるです。


3行目。 2行目で取得した親オブジェクト内に存在するポリゴンクラスタを取得しています。これも芋づる。


「クラスタの取得」と言っても、実際は Clusters プロパティを使って ClusterCollection として取得してますね。クラスタのコレクション=つまり、クラスタがいくつ存在するかは置いといて、ともかくクラスタの集合体として取得していることになります。クラスタが存在してなかったら何も入りません。

さらに、コレクションに効くメソッドのひとつである Filter を使って、ポリゴンクラスタのみを残しています。これによって oClusters に入るのはポリゴンクラスタのみになります。そのオブジェクトにポイントやエッジなどのクラスタがあったとしても Filter( "poly" ) ではじかれるので、最終的に oClusters には入らないということです。 別の方法で同じことをしようとすると、種類に関係なく見つかったクラスタは全部 oClusters に入れて、それから中身をひとつずつループし、タイプを調べてポリゴンクラスタのみを取り出すという方法もアリだと思いますが、今回のように「ポリゴンのみ扱うぜ」と仕様がはっきりしている時は、こっちの方が簡単だと思います。 実行も多分速い。


こんなとこですか。


改良の余地は死ぬほどありますね。いっぱい使うので、改良します。そのうち。たぶん。 ポリゴンクラスタ以外でも使えるようにしないと。




ごきげんよう。



.

|

« ○。 | トップページ | 2011以前でタブなスクリプトエディタ。 »

コメント

どもどもお疲れ様です。
身長は伸びてませんがPPGのところをxpopで選択するようにすると
OK押す手間が省けてより爽快になると考えますがどうでしょうどうでしょう?

投稿: ringpull(りんぷる | 2011年2月25日 (金) 02時56分

イエイそれ行きましょう。

XPOP2 バージョン
XPOP3 バージョン
そして最近は Qmenu なんてのもあるし
Qmenu なかなか便利です。まだカスタマイズしてないけど。  モデリングに便利。

それにしても伸びましたね。

投稿: junki | 2011年2月25日 (金) 03時29分

うわーこれは便利そう!使わせて頂きます!

投稿: Mitsuhiro Arita | 2011年2月25日 (金) 05時38分

有田さんどうぞ使って下さい。揉んで下さい。改良案お待ちしてます:D

投稿: junki | 2011年2月25日 (金) 13時30分

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: Add to クラスタの憂鬱。:

« ○。 | トップページ | 2011以前でタブなスクリプトエディタ。 »