« C4D テキストダイアログ | トップページ | StudioMOMO「C.O.F.F.E.E.でバッチレンダリング」… »

C4D 新たに、ポリゴンオブジェクトを一体化するスクリプトを作ってみよう。

新たに…
複数のポリゴンオブジェクトを一体化すると、一体化される前のオブジェクトの範囲が、わからなくなるよね…
分かり辛い言い回しか…

例えばオブジェクトA,B,Cを一体化すると、どこまでがAで、どこまでがBだったか。Cはどこまで?という事になる。

これを解決するには、一体化する前に、ABCそれぞれの全てのポリゴンを選択して、選択範囲に記録してから一体化すると、記録に残るわけだよね。

では、そんなスクリプトを簡単に組んでみよう。

スクリプトは、こんな感じです。

/*
オブジェクトの一体化、一体化前のオブジェクトの範囲を記録
2009.6.2

*/


main(doc , op)
{
  if(!object(1))return;//複数選択のチェック

  var mode = 0;//現在のモードを格納

  if(IsCommandChecked(12139))mode = 12139;  //ポイント
  if(IsCommandChecked(12187))mode = 12187;  //ポリゴン
  if(IsCommandChecked(12101))mode = 12101;  //オブジェクト
  if(IsCommandChecked(16351))mode = 16351;  //エッジ
  if(IsCommandChecked(12102))mode = 12102;  //オブジェクト軸
  if(IsCommandChecked(12298))mode = 12298;  //モデル
  if(IsCommandChecked(12184))mode = 12184;  //テクスチャ
  if(IsCommandChecked(12185))mode = 12185;  //テクスチャ軸
  if(mode == 0)mode = 12101;  //該当が無ければオブジェクト

  //ポリゴンを記録し一体化
  CallCommand(12187);  //ポリゴンモード
  CallCommand(13323);  //全て選択
  CallCommand(12552);  //選択範囲の記録
  CallCommand(12144);  //一体化

  CallCommand(mode);  //実行前のモードへ戻す
}

オブジェクトの複数選択チェックはobject(1)をチェックします。
object(0)をチェックしても選択オブジェクトの有無だけしかわかりません。
object(1)をチェックすることで複数選択されているかがわかります。
ただし、ポリゴンオブジェクトかどうかはチェックしていません。

実行前の編集モードを記録し、実行後元へ戻します。

既に一体化するために、オブジェクトが選択されているので、全てのポリゴンを選択は1回実行するだけで、選択された全てのオブジェクトに働きます。
選択範囲の記録も同様です。
なので、選択オブジェクトを捜査する必要がありません。

全体的にモードの記録が場所を占領していますね。
そもそも、元へ戻さなければ必要がありません。
モードチェックとモード切替は実行速度には全く問題ないので、関数にしても良いんですけどね。

一体化前のオブジェクトの範囲を記録したオブジェクトの一体化の主要部分は

  //ポリゴンを記録し一体化
  CallCommand(12187);  //ポリゴンモード
  CallCommand(13323);  //全て選択
  CallCommand(12552);  //選択範囲の記録
  CallCommand(12144);  //一体化

これだけです。
これだけでも良いんですけどね。

でも元のオブジェクトに取り付けた選択範囲タグは付いたままです。

メニューの状態です。

ENABLE = (object(1) != 0);

それでは、R9.5でも動くようにしてみます。
主要部分のCallCommand()も一体化以外、使わないで組んでみます。他にも少々…

/*
オブジェクトの一体化、一体化前のオブジェクトの範囲を記録 R9.5以上
2009.6.2
*/




//選択されたポリゴンオブジェクトの数を返します。
GetActivePolygonObjectCount(doc)
{
  var obj = GetActiveObject(doc);
  if(!obj)return 0;

  var c = 0;
  for(; obj ; obj = obj->SearchNext(BIT_AOBJ)){
    if(!instanceof(obj , PolygonObject))continue;
    c++;
  }
  return c;
}



main(doc , op)
{
  //複数選択されたオブジェクトがなければ終了
  var obj = GetActiveObject(doc);
  if(!obj)
    return;
  else if(!(obj->SearchNext(BIT_AOBJ)))return;

  var selobj_c = GetActivePolygonObjectCount(doc);//選択されたオブジェクト数
  var seltag = new(array , selobj_c);      //選択範囲タグ用
  var sel;   //選択範囲用

  var c = 0; //カウンター変数

  //オブジェクトの捜査
  for(; obj ; obj = obj->SearchNext(BIT_AOBJ)){
    if(!instanceof(obj , PolygonObject))continue;    //ポリゴンオブジェクト以外は除外
    sel = obj->GetPolygonSelection();      //オブジェクトのポリゴン選択範囲を取得
    sel->SelectAll(0 , obj->GetPolygonCount());      //全てを選択状態に
    seltag[c] = new(PolygonSelectionTag);  //新規にポリゴン選択範囲タグを取得
    seltag[c]->SetSelection(sel);          //選択範囲タグへ選択範囲を適用
    seltag[c]->SetName("[" + obj->GetName() + "]");  //タグへ名前を付ける
    obj->InsertTag(seltag[c]);             //オブジェクトへのタグの取り付け
    c++;
  }

  CallCommand(12144);  //一体化

  //元のオブジェクトに取り付けた選択範囲タグを削除
  for(c = 0 ; c < selobj_c ; c++)seltag[c]->Remove();
}

選択ポリゴンオブジェクトを数える関数を作らず、組み込んでもよかったんですけどね…
最後に元のオブジェクトに取り付けたタグを削除するために、選択範囲タグを配列変数に記憶させています。

このスクリプトで気を付けなければならない事は、ループ内で必ず新規のポリゴン選択範囲タグを取得することです。
ループ外で選択範囲タグを新規で取得して、それに選択範囲だけ変えてオブジェクトに取り付けると、C4Dがフリーズや強制終了するかもしれません。
下のコードは何が起こるかわからないので、危険です。

  var seltag = new(PolygonSelectionTag); //ポリゴン選択範囲タグを取得

  for(; obj ; obj = obj->SearchNext(BIT_AOBJ)){
    if(!instanceof(obj , PolygonObject))continue//ポリゴンオブジェクト以外は除外
    sel = obj->GetPolygonSelection();  //オブジェクトのポリゴン選択範囲を取得
    sel->SelectAll(0 , obj->GetPolygonCount());    //全てを選択状態に
    seltag->SetSelection(sel);         //選択範囲タグへ選択範囲を適用
    seltag->SetName("[" + obj->GetName() + "]");   //タグへ名前を付ける
    obj->InsertTag(seltag);            //オブジェクトへのタグの取り付け
    c++;
  }

タグには元のオブジェクトの名前を適用しました。

直接ポリゴン選択範囲タグを操作したので、モードチェック/切り替えはありません。

こちらのメニューの状態です。

  var obj = GetActiveObject(doc);
  if(!obj)
    ENABLE = FALSE;
  else ENABLE = (obj->SearchNext(BIT_AOBJ) != 0);

|

« C4D テキストダイアログ | トップページ | StudioMOMO「C.O.F.F.E.E.でバッチレンダリング」… »