« スクリプトでポリゴンオブジェクトを作成 | トップページ | ユーザースクリプトのフレームワーク »

スクリプトでポイントセレクト

ここ数回の実験で、スクリプトでオブジェクトを作成することが出来るようになったと思う。
こうなったら思いつくまま、ガンガン打ちまくる?いや、疲れた…
じゃあPointObjectのポイントを選択してみよう。PointObjectとはポリゴン/スプライン/FFDデフォーマかな?

/*
ポイントの選択
08.06.07
*/


if(!instanceof(op , PointObject))return;//ポイントオブジェクトではなければ処理を中止。
var pt_c = op->GetPointCount();if(!pt_c)return;//ポイント数。ポイントが無ければ処理を中止
var pt_sel = op->GetPointSelection();//opのポイントセレクションを得る。

pt_sel->Init();//ポイントセレクションを初期化
var i;

for(i = 0 ; i < pt_c / 2 ; i++)pt_sel->Select(i);//ポイントNo.の前半を選択状態にする。

op->SetPointSelection(pt_sel);//選択を適用

これでポイントの前半が選択状態になっています。構造マネージャで確認してみよう。
成功してますね。
PointObject->GetPointSelection()メンバ関数でポイント選択状況のBaseSelectクラスを取得する。Init()メンバ関数で全ての選択状況を解除します。これを実行しないと、現在の選択に追加される。Select()メンバ関数でポイントインデックスを渡し選択状態にする。
最後にオブジェクトに適用するためPointObjectクラスのSetPointSelection()メンバ関数を使う。

それでは、対称モデリング支援、軸から半分を選択する。を作ってみよう。ダイアログでコンボボックスを使い「選択領域」+X/-X/+Y/-Y/+Z/-Zが選択でき、「対称面を含む」チェックボックスで対称面上のポイントの選択させるか否かを選択する。最後にOK/キャンセルボタンで処理の実行/中止と。
では「スクリプトでモーダルダイアログ」で最後に作ったコードを元に…このコードをフレームワークにした方が、今後楽かなぁ。

とりあえずダイアログから。

/*
選択領域 オブジェクトの軸から半分を選択する
08.06.07
*/


class SelectArea_dialog : GeModalDialog
{
  public:
    var area;//追加
    var inc;//追加
    SelectArea_dialog();//変更
    Init();
    CreateLayout();
    AskClose();
}


SelectArea_dialog::SelectArea_dialog(){
  super();
  area = 1;//追加
  inc = TRUE;//追加
}


SelectArea_dialog::Init()
{
  SetInt(1002 , area , 1 , 6 , 1);//変更

  SetCheckbox(1003 , inc);//変更
}


SelectArea_dialog::CreateLayout()
{
  SetTitle("選択領域");
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "SelectArea" , 0);
    AddStaticText(1001 , 0 ,   0 , 0 , "領域" , 0);
    AddComboBox(1002 , 0 , 120 , 0);//コンボボックス
     AddItem(1002 , 1 , "+X");//追加
     AddItem(1002 , 2 , "-X");//追加
     AddItem(1002 , 3 , "+Y");//追加
     AddItem(1002 , 4 , "-Y");//追加
     AddItem(1002 , 5 , "+Z");//追加
     AddItem(1002 , 6 , "-Z");//追加
  AddGroupEnd();
  AddCheckbox(1003 , 0 , 150 , 0 , "対称面を含む");
  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);

}

SelectArea_dialog::AskClose()
{
  area = GetInt(1002);//ここを変更
  inc = GetCheckbox(1003);//ここも変更
}




main(doc , op)
{
  var SA_dialog = new(SelectArea_dialog);
  SA_dialog->Open(-1 , -1);
  if(!(SA_dialog->GetResult()))return;

}

この状態で実行するとダイアログが現れます。問題ないですね。説明も必要ないですね。
それでは、オブジェクトを軸から半分の領域を選択すると…

/*
領域選択 オブジェクトの軸から半分を選択する
08.06.07
*/


class SelectArea_dialog : GeModalDialog
{
  public:
    var area;
    var inc;
    SelectArea_dialog();
    Init();
    CreateLayout();
    AskClose();
}


SelectArea_dialog::SelectArea_dialog(){
  super();
  area = 1;
  inc = TRUE;
}


SelectArea_dialog::Init()
{
  SetInt(1002 , area , 1 , 6 , 1);

  SetCheckbox(1003 , inc);
}


SelectArea_dialog::CreateLayout()
{
  SetTitle("選択領域");
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "SelectArea" , 0);
    AddStaticText(1001 , 0 ,   0 , 0 , "領域" , 0);
    AddComboBox(1002 , 0 , 120 , 0);
     AddItem(1002 , 1 , "+X");
     AddItem(1002 , 2 , "-X");
     AddItem(1002 , 3 , "+Y");
     AddItem(1002 , 4 , "-Y");
     AddItem(1002 , 5 , "+Z");
     AddItem(1002 , 6 , "-Z");
  AddGroupEnd();
  AddCheckbox(1003 , 0 , 150 , 0 , "対称面を含む");
  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);

}

SelectArea_dialog::AskClose()
{
  area = GetInt(1002);
  inc = GetCheckbox(1003);
}


SelectArea(obj , areas , includes)
{
  var pt_c = obj->GetPointCount();if(!pt_c)return;
  var pt_sel = obj->GetPointSelection();
  var pt_pos = obj->GetPoints();


  pt_sel->Init();
  var i , sel;


  for(i = 0 ; i < pt_c ; i++){
    sel = FALSE;
    switch(areas){
      case 1:
        if(includes) sel = (pt_pos[i].x >= 0.0);
          else sel = (pt_pos[i].x > 0.0);
        break;
      case 2:
        if(includes) sel = (pt_pos[i].x <= 0.0);
          else sel = (pt_pos[i].x < 0.0);
        break;
      case 3:
        if(includes) sel = (pt_pos[i].y >= 0.0);
          else sel = (pt_pos[i].y > 0.0);
        break;
      case 4:
       if(includes) sel = (pt_pos[i].y <= 0.0);
          else sel = (pt_pos[i].y < 0.0);
        break;
      case 5:
       if(includes) sel = (pt_pos[i].z >= 0.0);
          else sel = (pt_pos[i].z > 0.0);
        break;
      case 6:
        if(includes) sel = (pt_pos[i].z <= 0.0);
          else sel = (pt_pos[i].z < 0.0);
        break;
    }
    if(sel)pt_sel->Select(i);
  }

  obj->SetPointSelection(pt_sel);
}

main(doc , op)
{
  var SA_dialog = new(SelectArea_dialog);
  SA_dialog->Open(-1 , -1);
  if(!(SA_dialog->GetResult()))return;


  if(!instanceof(op , PointObject))return;//ポイントオブジェクト意外だと中止
  SelectArea(op , SA_dialog->area , SA_dialog->inc);//追加
}

今回はポイントを配列で取得し、0.0より大きいか等の比較する。その結果でポイントを選択させる。
「メニューの状態」はポイントオブジェクトならばTRUE。それ以外がFALSE。

if(instanceof(op , PointObject))ENABLE = TRUE;else ENABLE = FALSE;

これで完成。改良すればポリゴンセレクトもできますね。今回のスクリプトは「SelectArea.ZIP」 です。アイコンがいまいち。
今回は、あまり目新しい事しなかったなぁ。なるべく新しいネタを…あるのか?

|

« スクリプトでポリゴンオブジェクトを作成 | トップページ | ユーザースクリプトのフレームワーク »

コメント

この記事へのコメントは終了しました。