« ユーザスクリプトで新規のスプライン | トップページ | スクリプトで階段押し出しNURBSの続き »

ユーザスクリプトで階段状のスプライン

前回のスプラインを新規に作成するスクリプトをベースにして、階段状のスプラインを作成。
今回の最終目的は、ダイアログでパラメータを設定して、階段状のスプラインの大きさと段数を入力してスプラインを作成するです。
では、いきなりですがスクリプトです。

/*
階段型スプライン
08.06.06
*/


var St_h = 100.0;//高さ
var St_l = 200.0;//長さ
var St_s = 10;//ステップ数

var n = St_s * 2 + 2;//総ポイント数

var sl = new(SplineObject);if(!sl)return;//スプラインオブジェクトを作成
var vc = new(VariableChanged);if(!vc)return;//ポイントデータ数の変更のためのVariableChanged

vc->Init(0 , n);//データ数の無い0からn個のデータ数へ変更
sl->MultiMessage(MSG_POINTS_CHANGED , vc);//変更をスプラインに適用

//垂直部
sl->SetPoint(0 , vector(0.0 , St_h , St_l / 2));
sl->SetPoint(1 , vector(0.0 ,  0.0 , St_l / 2));

//階段状データ
var i;
var St_sl , St_sh;

for(i = 0 ; i < St_s ; i++){
  St_sl = vector(0.0 , i     * St_h / St_s , -St_l / 2 + St_l / St_s * i);//段の下
  St_sh = vector(0.0 , (i+1) * St_h / St_s , -St_l / 2 + St_l / St_s * i);//段の上
  sl->SetPoint(i * 2 + 2 , St_sl);
  sl->SetPoint(i * 2 + 3 , St_sh);
}

sl#SPLINEOBJECT_CLOSED = TRUE;//スプラインを閉じる
sl->Message(MSG_UPDATE);//オブジェクトのアップデートをC4Dに伝える

doc->InsertObject(sl , NULL , NULL);//シーンに追加

前回とほとんど変わりありません。頭のほうで大きさなどの変数を設定して、変数値を変えると大きさや段数が変わります。

Steps

それでは、このスプラインの部分のスクリプトを関数にします。このままでも良いのですが…

AddStairSpline(doc , St_h , St_l , St_s)//St_h:高さ/St_l:長さ/St_s:ステップ数
{

  var n = St_s * 2 + 2;//総ポイント数

  var sl = new(SplineObject);if(!sl)return;//スプラインオブジェクトを作成
  var vc = new(VariableChanged);if(!vc)return;//ポイントデータ数の変更のためのVariableChanged

  vc->Init(0 , n);//データ数の無い0からn個のデータ数へ変更
  sl->MultiMessage(MSG_POINTS_CHANGED , vc);//変更をスプラインに適用

  //垂直部
  sl->SetPoint(0 , vector(0.0 , St_h , St_l / 2));
  sl->SetPoint(1 , vector(0.0 ,  0.0 , St_l / 2));

  //階段状データ
  var i;
  var St_sl , St_sh;

  for(i = 0 ; i < St_s ; i++){
    St_sl = vector(0.0 , i     * St_h / St_s , -St_l / 2 + St_l / St_s * i);//段の下
    St_sh = vector(0.0 , (i+1) * St_h / St_s , -St_l / 2 + St_l / St_s * i);//段の上
    sl->SetPoint(i * 2 + 2 , St_sl);
    sl->SetPoint(i * 2 + 3 , St_sh);
  }

  sl#SPLINEOBJECT_CLOSED = TRUE;//スプラインを閉じる
  sl->Message(MSG_UPDATE);//オブジェクトのアップデートをC4Dに伝える

  doc->InsertObject(sl , NULL , NULL);//シーンに追加
}

それでは、以前モーダルダイアログの実験で作成したスクリプトをコピーします。

/*
モーダルダイアログ実験
08.06.02
*/


var test_x = 2.56, test_y = 32.05;//適当な数です。

class test_dialog : GeModalDialog
{
  public:
    test_dialog();//コンストラクタ
    Init();//初期化
    CreateLayout();//ダイアログレイアウト
    AskClose();//ダイアログが閉じられたら
}

test_dialog::test_dialog(){super();}//コンストラクタ

test_dialog::Init()//初期化
{
  SetFloat(1002 , test_x , 0 , 100 , 1);//ここを変更
  SetFloat(1004 , test_y , 0 , 100 , 1);//ここも変更
}

test_dialog::CreateLayout()//ダイアログレイアウト
{
  SetTitle("テストダイアログ");//ダイアログのタイトル
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 , 0 , 0 , "testX" , 0);
    AddEditNumber(1002, 0, 150, 2);
    AddStaticText(1003 , 0 , 0 , 0 , "testY" , 0);
    AddEditNumber(1004, 0, 150, 3);
  AddGroupEnd();
AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);

}

test_dialog::AskClose()
{
  test_x = GetFloat(1002);//ここを変更
  test_y = GetFloat(1004);//ここも変更
}

main(doc , op)
{
  var t_dialog = new(test_dialog);//test_dialogクラスのt_dialogを作る
  t_dialog->Open(-1 , -1);//ダイアログを画面のマウスポインタの位置に開く
  if(!(t_dialog->GetResult()))return;

  println(test_x , " " , test_y , " ok!!");
}

このスクリプトを変更して階段状のスプラインを追加するスクリプトも追加します。
ここでは、ダイアログの説明はしません。変更部分のみコメントを追加します。

/*
階段状のスプラインを追加(ダイアログ付き)
08.06.06
*/


class test_dialog : GeModalDialog
{
  public:
    var dl_h , dl_l , dl_s;
    test_dialog();
    Init();
    CreateLayout();
    AskClose();
}

test_dialog::test_dialog()
{
  super();
  dl_h = 100.0;//ここを追加
  dl_l = 200.0;//ここを追加
  dl_s = 10;//ここを追加
}

test_dialog::Init()
{
  SetFloat(1002 , dl_h , 0 , 10000 , 0.1);//ここを変更
  SetFloat(1004 , dl_l , 0 , 10000 , 0.1);//ここを変更
  SetInt(1006 , dl_s , 1 , 10000 , 0.1);//ここを変更
}

test_dialog::CreateLayout()
{
  SetTitle("階段");//ここを変更
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 ,   0 , 0 , "高さ" , 0);//ここを変更
    AddEditNumber(1002 , 0 , 150 , 0);//ここを変更
    AddStaticText(1003 , 0 ,   0 , 0 , "長さ" , 0);//ここを変更
    AddEditNumber(1004 , 0 , 150 , 0);//ここを変更
    AddStaticText(1005 , 0 ,   0 , 0 , "段数" , 0);//ここを追加
    AddEditNumber(1006 , 0 , 150 , 0);//ここを追加
  AddGroupEnd();
AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);

}

test_dialog::AskClose()
{
  dl_h = GetFloat(1002);//ここを変更
  dl_l = GetFloat(1004);//ここを変更
  dl_s = GetInt(1006);//ここを変更
}

//ここからスプライン階段
AddStairSpline(doc , St_h , St_l , St_s)//St_h:高さ/St_l:長さ/St_s:ステップ数
{

  var n = St_s * 2 + 2;

  var sl = new(SplineObject);if(!sl)return;
  var vc = new(VariableChanged);if(!vc)return;

  vc->Init(0 , n);
  sl->MultiMessage(MSG_POINTS_CHANGED , vc);

  sl->SetPoint(0 , vector(0.0 , St_h , St_l / 2));
  sl->SetPoint(1 , vector(0.0 ,  0.0 , St_l / 2));

  var i;
  var St_sl , St_sh;

  for(i = 0 ; i < St_s ; i++){
    St_sl = vector(0.0 , i     * St_h / St_s , -St_l / 2 + i * St_l / St_s);
    St_sh = vector(0.0 , (i+1) * St_h / St_s , -St_l / 2 + i * St_l / St_s);
    sl->SetPoint(i * 2 + 2 , St_sl);
    sl->SetPoint(i * 2 + 3 , St_sh);
  }

  sl#SPLINEOBJECT_CLOSED = TRUE;
  sl->Message(MSG_UPDATE);

  doc->InsertObject(sl , NULL , NULL);
}


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

  AddStairSpline(doc , t_dialog->dl_h , t_dialog->dl_l , t_dialog->dl_s);//ここを追加
}

前回のモーダルダイアログ初期値の変数は、グローバル変数だったのをダイアログ(test_dialogクラス)のデータメンバにしました。段数が0のときC.O.F.F.E.E.エラーが起こります。ただダイアログで最小値が1になっているので0を入力しても1になります。ダイアログのコードは前回のまま使用しました。これで実行してください。階段状のスプラインがシーンに追加されます。

次に、このスプラインを「押し出しNURBS」を適用して階段にします。

/*
階段オブジェクト(ダイアログ付き)
08.06.06
*/


class test_dialog : GeModalDialog
{
  public:
    var dl_h , dl_l , dl_w , dl_s;//dl_wを追加
    test_dialog();
    Init();
    CreateLayout();
    AskClose();
}

test_dialog::test_dialog()
{
  super();
  dl_h = 100.0;
  dl_l = 200.0;
  dl_w = 50.0;//ここを追加
  dl_s = 10;
}

test_dialog::Init()
{
  SetFloat(1002 , dl_h , 0 , 10000 , 0.1);
  SetFloat(1004 , dl_l , 0 , 10000 , 0.1);
  SetFloat(1006 , dl_w , 0 , 10000 , 0.1);//ここを追加
  SetInt(1008 , dl_s , 1 , 10000 , 0.1);//ここのIDを変更
}

test_dialog::CreateLayout()
{
  SetTitle("階段");
  AddGroupBeginV(1000 , BFV_SCALEFIT , 2 , "test group" , 0);
    AddStaticText(1001 , 0 ,   0 , 0 , "高さ" , 0);
    AddEditNumber(1002 , 0 , 150 , 0);
    AddStaticText(1003 , 0 ,   0 , 0 , "長さ" , 0);
    AddEditNumber(1004 , 0 , 150 , 0);
    AddStaticText(1005 , 0 ,   0 , 0 , "幅" , 0);//ここを追加
    AddEditNumber(1006 , 0 , 150 , 0);//ここを追加
    AddStaticText(1007 , 0 ,   0 , 0 , "段数" , 0);//IDを変更
    AddEditNumber(1008 , 0 , 150 , 0);//IDを変更
  AddGroupEnd();
  AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);
}

test_dialog::AskClose()
{
  dl_h = GetFloat(1002);
  dl_l = GetFloat(1004);
  dl_w = GetFloat(1006);//ここを追加
  dl_s = GetInt(1008);//IDを変更
}

//ここからスプライン階段
AddStairSpline(doc , St_h , St_l , St_s)//St_h:高さ/St_l:長さ/St_s:ステップ数
{

  var n = St_s * 2 + 2;

  var sl = new(SplineObject);if(!sl)return;
  var vc = new(VariableChanged);if(!vc)return;

  vc->Init(0 , n);
  sl->MultiMessage(MSG_POINTS_CHANGED , vc);

  sl->SetPoint(0 , vector(0.0 , St_h , St_l / 2));
  sl->SetPoint(1 , vector(0.0 ,  0.0 , St_l / 2));

  var i;
  var St_sl , St_sh;

  for(i = 0 ; i < St_s ; i++){
    St_sl = vector(0.0 , i     * St_h / St_s , -St_l / 2 + i * St_l / St_s);
    St_sh = vector(0.0 , (i+1) * St_h / St_s , -St_l / 2 + i * St_l / St_s);
    sl->SetPoint(i * 2 + 2 , St_sl);
    sl->SetPoint(i * 2 + 3 , St_sh);
  }

  sl#SPLINEOBJECT_CLOSED = TRUE;
  sl->Message(MSG_UPDATE);

  return sl;//ここを変更
}


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

  var str_spl = AddStairSpline(doc , t_dialog->dl_h , t_dialog->dl_l , t_dialog->dl_s);//ここを変更 階段スプラインの作成
  str_spl->SetPosition(vector(t_dialog->dl_w / 2 , 0.0 , 0.0));//スプラインの位置調整
  var ext_obj = new(ExtrudeObject);//「押し出しNURBS」を作成
  ext_obj#EXTRUDEOBJECT_MOVE = vector(-t_dialog->dl_w , 0.0 , 0.0);//「押し出しNURBS」の押し出し方向と量
  doc->InsertObject(ext_obj , NULL , NULL);//「押し出しNURBS」を追加
  doc->InsertObject(str_spl , ext_obj , NULL);//「押し出しNURBS」を親にしてスプラインを追加
}

AddStairSpline()関数でのスプラインをシーンに追加するInsertObject()メンバ関数を削除し戻り値をスプラインオブジェクトにします。新規で「押し出しNURBS」を追加して、その子オブジェクトとしてシーンに追加します。
ダイアログに幅用のフィールドを追加し、その値を「押し出しNURBS」に適用します。
「押し出しNURBS」の軸がXY平面上でセンターになるようにスプラインの位置を調整。

残念なのはパラメータで操作できるのは作成時のみ。他のプリミティブのように変更も出来れば良いのですが…
あと追加機能としては階段の方向ですな。階段だから床面に設置しているから+X/-X/+Z/-Zで良いね。今は+Zですかねぇ。

次は何だろう…

|

« ユーザスクリプトで新規のスプライン | トップページ | スクリプトで階段押し出しNURBSの続き »

コメント

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