C4Dのポイントに新規ヌルオブジェクトを追加配置するユーザスクリプト
C4Dのポイント…スプラインやポリゴンオブジェクトのポイントです。
では、このポイントに新規のヌルオブジェクトを追加配置します。
他のツールの動作との整合性を考えて、動作させます。
ポイントが選択されていれば、選択されたポイントを対象に…
ポイントが選択されていなければ全てのオブジェクトのポイントを対象にします。
オブジェクトは複数選択に対応しましょう。
Undoも処理しましょう。
注意してくださいね。
ポイントの数だけヌルオブジェクトを追加するので、ポイント数が多いオブジェクトを対象にしないように…無駄にメモリーを消費します。
では、基本となるスクリプトを考えましょう。
選択された1つのオブジェクト。
ヌルオブジェクトを追加し選択されたポイントに配置します。
選択されたポイントが無ければ終了。
/*
選択されたポイントに新規ヌルオブジェクトを配置します。
2009.5.24
*/
main(doc , op)
{
var obj = op;//後に複数選択オブジェクトに対応する為のobj
if(!instanceof(obj , PointObject))return;//ポイントオブジェクト以外は対象外
var i; //カウンター変数
var gp; //追加するヌルオブジェクト用グループ
var nulobj;//追加するヌルオブジェクト用
var ptc = obj->GetPointCount(); //ポイント数の取得
var sel = obj->GetPointSelection();//ポイント選択状況の取得
var pts = obj->GetPoints(); //ポイントの取得
if(sel->GetCount()){ //選択されたポイントがあれば
gp = new(NullObject);//グループとしてのヌルオブジェクト
gp->SetName("group");//名前を変更
gp->InsertUnder(obj);//選択されたオブジェクトの子オブジェクトとしてシーンに追加
}else return;//選択されたポイントが無ければ終了
//ヌルオブジェクトを追加し選択されたポイントに配置する
for(i = 0 ; i < ptc ; i++){
if(sel->IsSelected(i)){ //ポイントが選択されていれば
nulobj = new(NullObject); //新規のヌルオブジェクトを用意
nulobj->InsertUnder(gp); //グループにヌルオブジェクトを追加
nulobj->SetName("point_" + tostring(i));//名前を変更
nulobj->SetPosition(pts[i]);//選択された位置を適用
}
}
}
このスクリプトを、ポリゴンオブジェクトやスプラインオブジェクトを選択して実行すると、選択されたポイントの位置にヌルオブジェクトが配置されます。
オブジェクトが複数選択されていたり、ポイントが選択されていなければ、何も起こりません。
では、ポイントが何も選択されていないと全てのポイントに配置するようにしてみよう。
/*
ポイントに新規ヌルオブジェクトを配置します。
2009.5.24
*/
main(doc , op)
{
var obj = op;
if(!instanceof(obj , PointObject))return;
var i;
var gp;
var nulobj;
var ptc = obj->GetPointCount();
var sel = obj->GetPointSelection();
var pts = obj->GetPoints(); //グループオブジェクトの追加
gp = new(NullObject);
gp->SetName("group");
gp->InsertUnder(obj);
//ヌルオブジェクトを追加し選択されたポイントに配置する
for(i = 0 ; i < ptc ; i++){
if(sel->IsSelected(i) || !(sel->GetCount())){
nulobj = new(NullObject);
nulobj->InsertUnder(gp);
nulobj->SetName("point_" + tostring(i));
nulobj->SetPosition(pts[i]);
}
}
}
ポイントに配置するヌルオブジェクトを格納するグループオブジェクトを無条件に追加します。
ポイントに配置するかしないかの判定は、
捜査したポイントが選択されているか?
sel->IsSelected(i)
もしくは、選択されたポイントが無いか?
!(sel->GetCount())
これで、オブジェクトを選択して実行してみよう。
ポイントが選択されていなければ、全てのポイントにヌルオブジェクトが配置されます。
選択されていれば、そのポイントに配置されます。
では、複数選択オブジェクトに対応させます。
/*
ポイントに新規ヌルオブジェクトを配置します。
2009.5.24
*/
main(doc , op)
{ var obj = GetActiveObject(doc);//複数選択オブジェクトの最初のオブジェクトを取得
if(!obj)return;//選択されたオブジェクトが無ければ終了
var i;
var ptc , pts , sel;
var nulobj;
var gp; //複数選択オブジェクトの処理
while(obj){//選択されたオブジェクトがあれば
if(instanceof(obj , PointObject)){//選択されたオブジェクトがポイントオブジェクトならば
//グループオブジェクトの追加
gp = new(NullObject);
gp->SetName("group");
gp->InsertUnder(obj);
ptc = obj->GetPointCount();
sel = obj->GetPointSelection();
pts = obj->GetPoints();
//ヌルオブジェクトを追加し選択されたポイントに配置する
for(i = 0 ; i < ptc ; i++){
if(sel->IsSelected(i) || !(sel->GetCount())){
nulobj = new(NullObject);
nulobj->InsertUnder(gp);
nulobj->SetName("point_" + tostring(i));
nulobj->SetPosition(pts[i]);
}
}
}
} obj = obj->SearchNext(BIT_AOBJ);//次の選択されたオブジェクトを取得
}
これで、複数オブジェクトに対応できます。
var obj = GetActiveObject(doc);
if(!obj)return;
これで、複数選択された最初のオブジェクトを取得します。
もし、取得できなければ終了します。
while(obj){
obj = obj->SearchNext(BIT_AOBJ);
}
while()とBaseList2D->SearchNext()を使い複数選択されたオブジェクトを捜査します。
捜査したオブジェクトのうち、ポイントオブジェクトを対象にし処理します。
では、最後にUndoに対応させます。
/*
ポイントに新規ヌルオブジェクトを配置します。
2009.5.24
*/
main(doc , op)
{
var obj = GetActiveObject(doc);
if(!obj)return;
var i;
var ptc , pts , sel;
var nulobj;
var gp; doc->StartUndo();//Undoの開始
//複数選択オブジェクトの処理
while(obj){
if(instanceof(obj , PointObject)){ doc->AddUndo(UNDO_OBJECT_REC , obj);//Undoに追加
//グループオブジェクトの追加
gp = new(NullObject);
gp->SetName("group");
gp->InsertUnder(obj);
ptc = obj->GetPointCount();
sel = obj->GetPointSelection();
pts = obj->GetPoints();
//ヌルオブジェクトを追加し選択されたポイントに配置する
for(i = 0 ; i < ptc ; i++){
if(sel->IsSelected(i) || !(sel->GetCount())){
nulobj = new(NullObject);
nulobj->InsertUnder(gp);
nulobj->SetName("point_" + tostring(i));
nulobj->SetPosition(pts[i]);
}
}
}
obj = obj->SearchNext(BIT_AOBJ);
}
} doc->EndUndo();//Undoの終了
今回のAddUndo()は、選択されたオブジェクトには変更がありませんが、子オブジェクトが追加変更されています。
ですから、オブジェクトの完全なデータと全ての子オブジェクトを保存する為、UNDO_OBJECT_RECを使い、選択された対象オブジェクトをヌルオブジェクト(group)が追加する前にUndoに保存します。
これで、スクリプト実行後にUndoをしてもヌルオブジェクトが追加される前に戻れます。
メニューの状態を忘れていました。
そのままでも良いのですが、オブジェクトが選択された時のみ有効にしましょう。
ENABLE = (GetActiveObject(doc) != NULL);
| 固定リンク