標準機能を使用するスクリプトの作成方法。

  • このフォーラムに新しいトピックを立てることはできません
  • このフォーラムではゲスト投稿が禁止されています

投稿ツリー



前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/10/4 19:36
asha  半人前   投稿数: 23
環境 249.2 Vista

お世話になっております。
この度、自作スクリプト作成に取り組んでおります。
作成までの大まかな流れは理解できたのですが、分からない場所がありましたので質問させていただきます。

スクリプトの最中で標準機能でカバーできる箇所があるため、作成中のpyの中から標準スクリプトを呼び出せないものだろうか?と考えました。
具体的に呼びたいのはCtrl+Aの「apply Scale and Rotate to obData」という機能です。

スクリプトがpyファイルとして存在する場合は
Blender.Run(script名)
と記述し実行して利用できるのは確認できたのですが、標準機能は可能なのでしょうか?(標準機能でpyファイルが.Blender/scriptの中に入っているものは現時点でも利用できます)
実装内容をすべて把握し手順をすべてプログラムしてやることで解決することは重々承知しているのですが、知識が乏しいこととバグを減らしたい観点から上記を利用したいと考えております。

まとめますと
・標準機能を自作スクリプト内で利用できるのかどうか?
・できるとすればどのようにするのか?
・操作などから目的の関数名?を探し出す方法やコツ
以上の3点を知りたいです。

分かりにくい文章で恐縮ですが、何卒よろしくお願い致します。
投票数:10 平均点:6.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/10/4 21:05
nanmo  常連   投稿数: 67
こんにちは。
なんもです。

標準機能を呼び出すというのであれば、擬似的にキーボードイベントを発生させる方法である程度は可能かと思います。
以前投稿されていたBlenderCommanderというスクリプトでの実装方法が参考になりそうです。

BlenderCommander(test)


#2.5では内部機構見直しで直接呼び出せるようになるかもわかりませんが

--
Webpage: http://bleble.s321.xrea.com/
Weblog : http://d.hatena.ne.jp/nanmo/

Break a leg!

投票数:4 平均点:2.50
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/10/5 18:52
asha  半人前   投稿数: 23
なんも様、ご回答ありがとうございます。

早速ですが、スクリプトを拝見しました。
実装部分から暫定的に必要そうな部分を抜き出しテキストエディタで実行してみました。


import Blender

winid = Blender.Window.GetScreenInfo(Blender.Window.Types.VIEW3D)[0]['id']

Blender.Window.SetKeyQualifiers(Blender.Window.Qual.CTRL)
Blender.Window.QAdd(winid, Blender.Draw.AKEY,1)
Blender.Window.QHandle(winid)
Blender.Window.QAdd(winid, Blender.Draw.AKEY,0)
Blender.Window.SetKeyQualifiers(0)


3D窓が無い場合などのエラー処理は含めておりませんが、とりあえず
「Ctrl+A」
のメニューを表示させることができました。
ものによっては上記の実装で解決していたと思います。

しかしながら今回、問題になったのがメニュー(ポップアップ?)の中から1番上のものを選択させる処理です。
安易にONEKEYやエンターを押させれば良いだろうと思っていたのですが、どうもメニュー選択処理を実行しないとスクリプトが先に進んでくれないようで手の打ちようがありません。(メニューWhileで回していてスレッドを完全に止めているような挙動をしています)

是非、先人方の知恵をお貸しください。よろしくお願いします。

投票数:18 平均点:1.67
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/10/6 7:37
yamyam  管理人 居住地: そうや、うちはおおさかやー  投稿数: 4405
なんとなく邪道かつ本筋から離れている気がしますが、AutoHotKey で以下のようなスクリプトを作成し、os.system()なんかで実行されるのはどうでしょう?
#IfWinActive ahk_class GHOST_WindowClass
Send,^a
Send,1
return
#IfWinActive

実際に呼び出して試してないのでもしかしたらIFWinActiveはいらないかもしれません。
泥縄ですが、それっぽい関数見つからなかったもので。
投票数:27 平均点:1.11
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2009/10/8 13:21
asha  半人前   投稿数: 23
yamyam様、回答に感謝致します。

ご提示いただいた方法ですが、懸念されている通り使いにくさを払拭できません。
スクリプトを配布しにくくなるのが最大の理由です。

しかしながら情報が無い中、模索していただいたことに大変感謝しております。

今回は2.5に期待しつつ、「実行内容を自前で用意する」方向でアプローチしてみることにします。
本当にありがとうございました。失礼致します。
投票数:4 平均点:2.50
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2009/10/10 1:15
uimac  常連   投稿数: 49
私も少し考えてみましたが、自前で実装するのが一番早いと思います。
BlenderのMeshとArmatureのみで、ついでにShapeKey付きMeshに対応した「apply Scale and Rotate to obData」は、下記。
pythonからアクセスする手段は無いに等しいです。

// src/editobject.c
// static void apply_objects_internal( int apply_scale, int apply_rot )
{
	Base *base, *basact;
	Object *ob;
	bArmature *arm;
	Mesh *me;
	MVert *mvert;
	float mat[3][3];
	int a, change = 0;
	
	float *fp;
	KeyBlock *block;
	
	if (!apply_scale && !apply_rot) {
		/* do nothing? */
		error("Nothing to do!");
		return;
	}
	/* first check if we can execute */
	for (base= FIRSTBASE; base; base= base->next) {
		if TESTBASELIB(base) {
ob= base->object;
if(ob->type==OB_MESH) {
	me= ob->data;
	
	if(me->id.us>1) {
		error("Can't apply to a multi user mesh, doing nothing.");
		return;
	}
	// by uimac
	//if(me->key) {
	//	error("Can't apply to a mesh with vertex keys, doing nothing.");
	//	return;
	//}
}
else if (ob->type==OB_ARMATURE) {
	arm= ob->data;
	
	if(arm->id.us>1) {
		error("Can't apply to a multi user armature, doing nothing.");
		return;
	}
}
		}
	}
	
	/* now execute */
	basact= BASACT;
	base= FIRSTBASE;
	for (base= FIRSTBASE; base; base= base->next) {
		if TESTBASELIB(base) {
ob= base->object;

if(ob->type==OB_MESH) {
	if (apply_scale && apply_rot)
		object_to_mat3(ob, mat);
	else if (apply_scale)
		object_scale_to_mat3(ob, mat);
	else
		object_rot_to_mat3(ob, mat);

	me= ob->data;
	
	// by uimac
	if(me->key) {
	 for (block = (KeyBlock*)me->key->block.first; block; block = block->next) {
	  fp = (float*)block->data;
	  for(a = 0; a < block->totelem; a++, fp+= 3) {
	   Mat3MulVecfl(mat, fp);
	  }
	 }
	}

	/* see checks above */
	
	mvert= me->mvert;
	for(a=0; a<me->totvert; a++, mvert++) {
		Mat3MulVecfl(mat, mvert->co); // 要はこれ
	}
	if (apply_scale)
		ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
	if (apply_rot)
		ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
	/*QuatOne(ob->quat);*/ /* Quats arnt used yet */
	
	where_is_object(ob);
	
	/* texspace and normals */
	BASACT= base;
	enter_editmode(EM_WAITCURSOR);
	BIF_undo_push("Applied object");	/* editmode undo itself */
	exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
	BASACT= basact;
	
	change = 1;
}
else if (ob->type==OB_ARMATURE) {
	if (apply_scale && apply_rot)
		object_to_mat3(ob, mat);
	else if (apply_scale)
		object_scale_to_mat3(ob, mat);
	else
		object_rot_to_mat3(ob, mat);
	arm= ob->data;
	
	/* see checks above */
	apply_rot_armature(ob, mat); //他のファイルで定義されてますね。ググると出てきます
	
	/* Reset the object's transforms */
	if (apply_scale)
		ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
	if (apply_rot)
		ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
	/*QuatOne(ob->quat); (not used anymore)*/
	
	where_is_object(ob);
	
	change = 1;
}

// 以下略

投票数:13 平均点:7.69

  条件検索へ


ログイン

ユーザ名:

パスワード:



パスワード紛失

クイックリンク

2021/07/01版
●Blender.org
BlenderFoundation
- Blenderのダウンロード
- 公式チュート等
- 公式マニュアル(和訳)

●ニュース(英文)
BlenderNation

●Blenderコミュニティ
blenderartists.org

●Blender Q&A
- Blender Stack Exchange

●テストビルド
Buildbot(自動生成)


●開発関連
公式開発サイト
Blender開発blog
Blender Wiki