C++プログラムからBlenderをリアルタイム操作

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

投稿ツリー



前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2013/4/8 22:11
ys77  新米   投稿数: 4
初めて投稿いたします。よろしくお願いいたします。
C++プログラムから、Blenderをリアルタイムで操作したいと考えています。
OSはWindows 7(64bit)で、Blenderのバージョンはv.2.66.1です。

現在、
FILE *out_pipe = _popen("C:\\Research\\ref\\Blender\\blender.exe -P C:\\Research\\ref\\Blender\\mycommand.py","w");
として、_popen関数を使ってプロセス間通信をして、Blenderの起動時にpythonのスクリプトを読み込ませることは出来ています。

ですが、Blender起動後に、以下のようにfputs関数でpythonコマンドを送っても動作しません。
fputs("bpy.data.objects['Cube'].location.x = bpy.data.objects['Cube'].location.x + 5 \n", out_pipe);

リアルタイムでpythonコマンドを出すことはできないのでしょうか?

もしリアルタイムでBlenderを操作する場合は、Blenderのソースコードを変更してプロセス間通信をできるようにしないといけないのでしょうか?
ご存知の方教えてください。
よろしくお願いいたします。


投票数:7 平均点:5.71
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2013/4/11 11:41
yamyam  管理人 居住地: そうや、うちはおおさかやー  投稿数: 4405
初めまして。
引用:
もしリアルタイムでBlenderを操作する場合は、Blenderのソースコードを変更してプロセス間通信をできるようにしないといけないのでしょうか?
結論からいうとそうだと思います。むしろなぜ動作すると思ったのか訊きたいところなのですが…書かれているBlenderの起動は単にスイッチつけて起動させているだけですし、プロセス間通信でPythonコードを実行するような機能はなかったように思います。

Pythonコードを送り込んで実行したいなら、Blender側でSimpleXMLRPCServerを使ったPythonスクリプトを実行し、もらった文字列を読み込んでEvalするスクリプトでも書けばいけそうな気がします。

投票数:13 平均点:1.54
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2013/4/13 16:26
ys77  新米   投稿数: 4
yamyam様

お返事が遅くなって失礼致しました。ys77です。
やはりプロセス間通信が必要なのですね。
どうもありがとうございました。
大変助かりました。

早速試してみました。
BlenderのpythonではSimpleXMLRPCServerは含まれていないようだったので、
ソケット通信を使って、以下のようなpythonスクリプトを書きました。
これでクライアント側からpythonコマンドを送信したところ、無事実行されました。
ですが、ひとつ問題があります。

pythonコマンドを受信した後にexec関数で実行していますが、
その時点ではBlenderの3DViewには何も反映されず、
スクリプトが終わった時点でまとめて反映されます。
exec関数を実行した時点でリアルタイムにBlenderに反映したいのですが、
どのようにすれば良いかお分かりになりますでしょうか。

どうぞよろしくお願いいたします。

-------------------------------------
from socket import *
HOST = 'localhost'
PORT = 9000
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))

(conn, addr) = s.accept()
print( 'Connected by', addr)
cnt = 0

while cnt < 10000000:
    cnt += 1
    tmp_data = conn.recv(1024)
    data = tmp_data.decode()
    exec(data)
    print("exec( ", data, " )")

conn.close()

投票数:3 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 | 投稿日時 2013/4/13 23:23
ys77  新米   投稿数: 4
ys77です。
一つ前の投稿で質問した件(リアルタイムでpythonコマンドを実行)ですが、
自分で解決できましたのでご報告します。

・pythonのthreadingをimport
・スレッドを新しく作る。ここで、setDaemon(True)としてデーモンにしておく。
・上記スレッド内で、ソケット通信のモジュールを呼ぶ。

こうすると、親プロセスはすぐに終了するので、Blenderはすぐに起動されました。
そして、生き残ったデーモンがサーバーとなり、pythonコマンドを受信して、
リアルタイムに実行することが出来ました。

情報共有のため、以下にpythonスクリプトを載せておきます。
どうも有り難うございました。

#-------------【call_serversocket.py】 呼び出し側 ----------------------
#------------- ./blender -P call_serversocket.py と起動時に実行 --------

import threading
import time
from called_serversocket import serverclass

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.i = 0

    def run(self):
        print("Start.")
        serverclass.serversocket()
        print("serverclass.serversocket() start!")

if __name__ == "__main__":
    t = test()
    t.start()
    print("call_serversocket end!")


#-------------【called_serversocket.py】 呼び出される側 ----------------------
from socket import *

class serverclass:
    
    def serversocket():
        print( 'serversocket() ')

        HOST = 'localhost'
        PORT = 9000
        s = socket(AF_INET, SOCK_STREAM)
        s.bind((HOST, PORT))
        s.listen(1)
        
        (conn, addr) = s.accept()
        print( 'Connected by', addr)
        cnt = 0
        while 1:
            cnt += 1
            tmp_data = conn.recv(1024)
            data = tmp_data.decode()
            exec(data)
            print("exec( ", data, " )")
 
       conn.close()

投票数:9 平均点:4.44
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2013/4/14 22:08
atassyu  半人前 居住地: Tokyo  投稿数: 21
 ys77 さんの書き込みを元に

Windows7(x86-32)
Blender 2.66.1

の環境で、

C#: VS Express 2012 for Desktop

を使っての、Blender のリアルタイム操作に挑んでみました。

 ファイル call_serversocket.py には

import threading

が必要だと思います。

 一応、文字列を送って受け取る、ところまでは出来ました。

 \n 区切りの文字列を送って、\n を受け取ったら exec するようにできたら、
.zip で固めて、自分の Web ででも、発表するつもりですが、ys77 さん、よろしいでしょうか ?

 html だと、Python にとって重要なインデントがなくなっちゃうので。

 では、また。


あたっしゅ(MrAtassyu)
投票数:4 平均点:5.00
前の投稿 - 次の投稿 | 親投稿 - | 投稿日時 2013/4/15 11:29
yamyam  管理人 居住地: そうや、うちはおおさかやー  投稿数: 4405
大してお役に立てなかったので恐縮です。(汗

あと、atassyuさんも触れられていますが、インデントが反映されていないので、勝手ながらCode BBコード(レス入力フィールドで文字列を追加して<>アイコンをクリック)でインデントが反映されるようソースコード部分に手を加えさせていただきました。
投票数:3 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2013/4/20 11:57
ys77  新米   投稿数: 4
atassyu様、yamyam様

ys77です。返信ありがとうございます。
同じようなことを試みている方がいらして心強いです。
import threadingの部分をコピーし忘れていましたので、
追記しました。コードはご自由に使っていただいて結構です。

もう一点解決できないことがあります。
BVH形式のアニメーションファイルを読み込みたいと思い、
 bpy.ops.import_anim.bvh(filepath="ファイル名")
をexec関数で実行すると、以下のようなエラーが出ます。
 bpy.ops.object.set_mode.poll() failed, context is incorrect

ちなみに、BlenderのGUIのpython consoleでは、
上記コマンドで問題なく読み込めます。

調べたところ、マウスの位置かモードが適切でないようなのですが、
どなたか解決方法お分かりになる方いらっしゃいますか?

なお、
 bpy.ops.object.mode_set(mode='モード名')
とモードを変更しようとしても、同じエラーが出てしまいます。

よろしくお願いします。

投票数:2 平均点:5.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2013/4/22 12:04
yamyam  管理人 居住地: そうや、うちはおおさかやー  投稿数: 4405
状況がよくわからないのですが、対象のArmatureが Scene に正しくリンクされていない、またはアクティブオブジェクトになっていない可能性があります。
下記の記事を参照してみてください。
http://blenderartists.org/forum/showthread.php?206073-quot-Context-is-Invalid-quot
投票数:6 平均点:5.00

  条件検索へ


ログイン

ユーザ名:

パスワード:



パスワード紛失

クイックリンク

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

●ニュース(英文)
BlenderNation

●Blenderコミュニティ
blenderartists.org

●Blender Q&A
- Blender Stack Exchange

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


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