トップページ

スクリプト関係のメモ

製作者:morita 更新日:2004-05-16

OR'ed value(OR結合)の説明

(環境:Blender2.31 Python2.2.3 Windows98)

1つのフラグ変数に複数の状態を記憶するための方法です。 状態を取得・設定するには、ビット演算を使います。

・フラグにモードがセットされているか調べる方法

(以下の例では、meはメッシュデータです。)

if me.mode & NMesh.Modes['SUBSURF']:
  print('SUBSURFはオンですよ')

このようにModes辞書に定義されてるモードとアンド演算をします。Trueならそのモードはオンだということです。

以下のようにnotをつければ、モードがオフかどうか調べられます。

if not me.mode & NMesh.Modes['SUBSURF']:
  print('SUBSURFはオフですよ')

・フラグにモードをセットする方法

&(論理積)、|(論理和)~(ビット反転)、^(排他的論理和)を使っていろいろな設定ができます。

オンにする:me.mode = me.mode | NMesh.Modes['SUBSURF']
オフにする:me.mode = me.mode & ~NMesh.Modes['SUBSURF']
オンオフを反転:me.mode = me.mode ^ NMesh.Modes['SUBSURF']
このモードだけオン(他モードは全部オフになる):me.mode = me.mode & NMesh.Modes['SUBSURF']

他の演算と同じように、演算子をイコールの前に置いて、次のように書くこともできます。

オフにする:me.mode &= ~NMesh.Modes['SUBSURF']

スライダー等のGUI部品の値を取得する方法

(環境:Blender2.31 Python2.2.3 Windows98)

スライダー等のGUI部品の値を取得するには、あらかじめ、GUI部品の値を記憶するオブジェクトを、グローバル領域に作っておきます。

value = Create(0) # value.valで値を参照できます

GUI部品の作成時に、値記憶オブジェクトを左辺に置きます。

value=Slider("Test Slider",1, 10,10,200,20, value.val, 0, 150)

これで、このスライダーの値をvalueオブジェクトで参照できるようになりました。このスライダーのイベントをキャッチしたときに、value.valの値を見れば、ユーザーの入力値が分かります。

以上で分かったように、イベントと入力値は独立しています。GUIプログラムを作るときは、イベントが起こったときに、グローバル領域にあるオブジェクトから入力値を取得する、という流れになるようです。

スクリプト例

スライダーの値を表示するだけです。

import Blender
from Blender.BGL import *
from Blender.Draw import *

value = Create(0) # 値を記憶するオブジェクト

def draw():
  global value
  glClear(GL_COLOR_BUFFER_BIT)
  # スライダーの作成
  value = Slider("Slider",1, 10,10,200,20, value.val, 0, 150, 0)

def event(evt, val):
  if (evt == QKEY and not val):
    Exit() # Qキーを押したら終了

def bevent(evt):
  global value
  if evt == 1: # イベント番号を照合する
    print value.val # スライダーの値を表示する

Register(draw, event, bevent)

初期値について

スライダーの作成時に、value.valを初期値にしています。ここに適当な値(例えば0)を直接書くと、GUIが再描画されたときに、スライダーの値が初期値(例えば0)に戻ってしまいます。value.valにしておけば、そのときのvalueの値で再描画されます。


GUIのページ切替

(環境:Blender2.31 Python2.2.3 Windows98)

一度に見えるボタンが多すぎると、どれを操作すればいいか混乱します。内容別にページを分けると、分かりやすくなると思います。

ページ切替処理の流れ

ページボタンが押されたら、ページ番号を変え、ページ番号に合わせてGUIを再描画する。

実際の手順

まず、現在のページ番号を記憶する変数を、グローバル領域に作ります。

CurrentPage = 1

GUIを描画する関数では、常に表示するページボタンをはじめに作ります。

  Button("Page1",1 , 10, 10, 50, 18)
  Button("Page2",2 , 70, 10, 50, 18)

その次に、ページごとに表示する内容を作ります。これで、ページ番号ごとに別々のGUIが表示されます。

  if CurrentPage == 1:
    Button("Button1",100 , 20, 40, 150, 18)
  if CurrentPage == 2:
    Button("Button2",200 , 30, 40, 120, 40)

最後に、ページボタンが押されときに、ページ番号変数の値を変え、Register関数を呼び出すようにします。これで、ページボタンを押すと、GUIが再描画されます。

  if evt == 1:
    CurrentPage = 1
    Register(draw, event, bevent)
  if evt == 2:
    CurrentPage = 2
    Register(draw, event, bevent)

以上で、ページを切替できるようになりました。

スクリプト例

3つのページを切替できます。(ページの中のボタンは何も反応しません。)

# MultiPage.py: GUIのページ切替をする
import Blender
from Blender.BGL import *
from Blender.Draw import *

CurrentPage = 1 # ページ番号を記憶する変数

def draw():
  global CurrentPage
  glClear(GL_COLOR_BUFFER_BIT)
  # どのページにも表示するボタン
  Button("Page1",1 , 10, 10, 50, 18)
  Button("Page2",2 , 70, 10, 50, 18)
  Button("Page3",3 , 130, 10, 50, 18)
  if CurrentPage == 1:
    # Page1に表示する内容
    Button("Button1",100 , 20, 40, 150, 18)
  if CurrentPage == 2:
    # Page2に表示する内容
    Button("Button2",200 , 30, 40, 120, 40)
  if CurrentPage == 3:
    # Page3に表示する内容
    Button("Button3",300 , 50, 40, 70, 70)

def event(evt, val):
  if (evt == QKEY and not val):
    Exit() # Qキーを押したら終了

def bevent(evt):
  global CurrentPage
  if evt == 1:
    CurrentPage = 1               # ページ番号をセットして
    Register(draw, event, bevent) # GUIを再描画する
  if evt == 2:
    CurrentPage = 2
    Register(draw, event, bevent)
  if evt == 3:
    CurrentPage = 3
    Register(draw, event, bevent)

Register(draw, event, bevent)

イベント番号に8を使うな!

(環境:Blender2.31&2.32 Python2.2.3 Windows98)

(環境:Blender2.33 Python2.3 Windows98)

(これはBlender2.33での問題です。将来のバージョンでは直ってるかもしれません。)

Draw.Menu()で作ったメニューを操作したときに、何も選ばずメニューを閉じると、8という値のイベントが発生します。こんなイベント要らないと思うんですが、何であるんでしょう。

他のイベントと間違うのを回避するために、イベント番号には8を使わないようにしましょう。

(Blender2.32までは、メニューを選択したときに4という値のイベントも発生していました。2.32以前のBlenderでもスクリプトを使用する可能性があるなら、4も使わないほうが良いでしょう。)