Pivy/ja: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
(Updating to match new version of source page)
Line 1: Line 1:
<languages/>
<languages/>
{{docnav|Scenegraph|PySide}}
{{docnav|Scenegraph|PySide}}

== Introduction ==


<div class="mw-translate-fuzzy">
<div class="mw-translate-fuzzy">
Line 6: Line 8:
</div>
</div>


<div class="mw-translate-fuzzy">
Coinライブラリはいくつかに分割されています。Coin自体はシーングラフの操作を担い、Windowsといった複数のGUIシステム用のパッケージがありますが私たちの場合はQt用になります。これらの分割されたモジュールもシステム上に存在する場合にはPivyから利用することができます。Coinモジュールは常駐していて自由に利用することができます。既にFreeCADによって行われているので3D表示をどのインターフェイスに紐付けするのか気にする必要はありません。私たちがやらなければならないのは以下のコマンドを実行することだけです:
Coinライブラリはいくつかに分割されています。Coin自体はシーングラフの操作を担い、Windowsといった複数のGUIシステム用のパッケージがありますが私たちの場合はQt用になります。これらの分割されたモジュールもシステム上に存在する場合にはPivyから利用することができます。Coinモジュールは常駐していて自由に利用することができます。既にFreeCADによって行われているので3D表示をどのインターフェイスに紐付けするのか気にする必要はありません。私たちがやらなければならないのは以下のコマンドを実行することだけです:
</div>
{{Code|code=
{{Code|code=
from pivy import coin
from pivy import coin
}}
}}

==シーングラフへのアクセスと変更==
==シーングラフへのアクセスと変更==


<div class="mw-translate-fuzzy">
典型的なCoinシーンがどの様に構成されているかは[[Scenegraph/jp|シーングラフ]]ページで見ました。FreeCADの3Dビューに表示されているものは全てCoinシーングラフであり、同じやり方で構成されています。ルートのノードが一つあり、画面上のオブジェクトは全てその子ノードです。
典型的なCoinシーンがどの様に構成されているかは[[Scenegraph/jp|シーングラフ]]ページで見ました。FreeCADの3Dビューに表示されているものは全てCoinシーングラフであり、同じやり方で構成されています。ルートのノードが一つあり、画面上のオブジェクトは全てその子ノードです。
</div>


FreeCADでは3Dビューシーングラフのルートノードに簡単にアクセスすることができます:
FreeCADでは3Dビューシーングラフのルートノードに簡単にアクセスすることができます:
{{Code|code=
{{Code|code=
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print sg
print(sg)
}}
}}

こうするとルートノードが返されます。
こうするとルートノードが返されます。
{{Code|code=
{{Code|code=
<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >
<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >
}}
}}

シーンの直下の子ノードを調べることもできます。
シーンの直下の子ノードを調べることもできます。
{{Code|code=
{{Code|code=
for node in sg.getChildren():
for node in sg.getChildren():
print node
print(node)
}}
}}

<div class="mw-translate-fuzzy">
<div class="mw-translate-fuzzy">
SoSeparatorsやSoGroupsといったこれらノードは自身の子ノードを持ちます。利用可能なCoinオブジェクトの全リストは[http://doc.coin3d.org/Coin/classes.html Coin公式ドキュメント]にあります。
SoSeparatorsやSoGroupsといったこれらノードは自身の子ノードを持ちます。利用可能なCoinオブジェクトの全リストは[http://doc.coin3d.org/Coin/classes.html Coin公式ドキュメント]にあります。
Line 35: Line 45:
{{Code|code=
{{Code|code=
col = coin.SoBaseColor()
col = coin.SoBaseColor()
col.rgb=(1,0,0)
col.rgb = (1,0,0)
cub = coin.SoCube()
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode = coin.SoSeparator()
Line 42: Line 52:
sg.addChild(myCustomNode)
sg.addChild(myCustomNode)
}}
}}

(すてきな)赤い立方体ができました。以下を試してみてください:
(すてきな)赤い立方体ができました。以下を試してみてください:
{{Code|code=
{{Code|code=
col.rgb=(1,1,0)
col.rgb = (1, 1, 0)
}}
}}

わかったでしょうか?実行中であっても全てのものに対してアクセスと変更を行うことができるのです。再計算や再描画は必要ありません。Coinが全て面倒を見てくれます。物体のシーングラフへの追加、プロパティの変更、物体の非表示、一時的なオブジェクトの表示、何でもできます。もちろん3Dビューに関係したことだけですが。この表示はFreeCADがファイルを開いた時とオブジェクトが必要とした時に再計算されます。従って既存のFreeCADオブジェクトの外見を変更した場合、その変更はオブジェクトが再計算されるかファイルを再度開いた瞬間に失われます。
わかったでしょうか?実行中であっても全てのものに対してアクセスと変更を行うことができるのです。再計算や再描画は必要ありません。Coinが全て面倒を見てくれます。物体のシーングラフへの追加、プロパティの変更、物体の非表示、一時的なオブジェクトの表示、何でもできます。もちろん3Dビューに関係したことだけですが。この表示はFreeCADがファイルを開いた時とオブジェクトが必要とした時に再計算されます。従って既存のFreeCADオブジェクトの外見を変更した場合、その変更はオブジェクトが再計算されるかファイルを再度開いた瞬間に失われます。


Line 61: Line 73:
sg.addChild(myCustomNode)
sg.addChild(myCustomNode)
}}
}}

OpenInventorのシーングラフではその順番が重要であるということを思い出してください。ノードは以降のノードに影響を与えます。color red、cube、color yellow、sphere とすれば赤い立方体と黄色い球が表示されます。もし今、既存の自作ノードに移動を追加すると移動は立方体の後になり、立方体に影響を与えません。上記のように作成時に挿入しておけば次のようにできます:
OpenInventorのシーングラフではその順番が重要であるということを思い出してください。ノードは以降のノードに影響を与えます。color red、cube、color yellow、sphere とすれば赤い立方体と黄色い球が表示されます。もし今、既存の自作ノードに移動を追加すると移動は立方体の後になり、立方体に影響を与えません。上記のように作成時に挿入しておけば次のようにできます:
{{Code|code=
{{Code|code=
trans.translation.setValue([2,0,0])
trans.translation.setValue([2,0,0])
}}
}}

<div class="mw-translate-fuzzy">
こうすると立方体が2単位分、右に移動します。
こうすると立方体が2単位分、右に移動します。
最後に何かを取り除くには次のようにします:
最後に何かを取り除くには次のようにします:
</div>
{{Code|code=
{{Code|code=
sg.removeChild(myCustomNode)
sg.removeChild(myCustomNode)
Line 78: Line 94:
{{Code|code=
{{Code|code=
class ButtonTest:
class ButtonTest:
def __init__(self):
def __init__(self):
self.view = FreeCADGui.ActiveDocument.ActiveView
self.view = FreeCADGui.ActiveDocument.ActiveView
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick)
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick)

def getMouseClick(self,event_cb):
event = event_cb.getEvent()
def getMouseClick(self,event_cb):
if event.getState() == SoMouseButtonEvent.DOWN:
event = event_cb.getEvent()
if event.getState() == SoMouseButtonEvent.DOWN:
print "Alert!!! A mouse button has been improperly clicked!!!"
print("Alert!!! A mouse button has been improperly clicked!!!")
self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback)
self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback)
ButtonTest()
ButtonTest()
}}
}}

<div class="mw-translate-fuzzy">
<div class="mw-translate-fuzzy">
コールバックが起きた時にもオブジェクトは実行され続けなければならないのでコールバックはオブジェクトで初期化されなけれればなりません。
コールバックが起きた時にもオブジェクトは実行され続けなければならないのでコールバックはオブジェクトで初期化されなけれればなりません。
Line 109: Line 127:
}}
}}


* [https://github.com/coin3d Coin3d] homepage
* [https://github.com/coin3d/pivy Pivy] homepage
* [https://grey.colorado.edu/coin3d/index.html Coin Documentation], at University of Colorado
* [https://grey.colorado.edu/coin3d/index.html Coin Documentation], at University of Colorado
* [https://coin3d.bitbucket.io/Coin/index.html Coin Documentation], at BitBucket
* [https://coin3d.bitbucket.io/Coin/index.html Coin Documentation], at BitBucket
Line 114: Line 134:
{{docnav|Scenegraph|PySide}}
{{docnav|Scenegraph|PySide}}


{{Powerdocnavi{{#translation:}}}}
{{Userdocnavi}}

[[Category:Poweruser Documentation]]

{{clear}}
{{clear}}

Revision as of 20:15, 15 May 2020

Scenegraph
PySide

Introduction

PivyはFreeCADで使われている3DレンダリングライブラリであるCoin3d用のPythonのバインディングライブラリです。実行中のPythonインタプリタにインポートするとFreeCADの3DビューアーなどのCoin3dシーングラフと直に対話処理を行ったり、新しい3Dビューアーを作成することさえできます。Pivyは標準のFreeCADインストールに同梱されています。

Coinライブラリはいくつかに分割されています。Coin自体はシーングラフの操作を担い、Windowsといった複数のGUIシステム用のパッケージがありますが私たちの場合はQt用になります。これらの分割されたモジュールもシステム上に存在する場合にはPivyから利用することができます。Coinモジュールは常駐していて自由に利用することができます。既にFreeCADによって行われているので3D表示をどのインターフェイスに紐付けするのか気にする必要はありません。私たちがやらなければならないのは以下のコマンドを実行することだけです:

from pivy import coin

シーングラフへのアクセスと変更

典型的なCoinシーンがどの様に構成されているかはシーングラフページで見ました。FreeCADの3Dビューに表示されているものは全てCoinシーングラフであり、同じやり方で構成されています。ルートのノードが一つあり、画面上のオブジェクトは全てその子ノードです。

FreeCADでは3Dビューシーングラフのルートノードに簡単にアクセスすることができます:

sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print(sg)

こうするとルートノードが返されます。

<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >

シーンの直下の子ノードを調べることもできます。

for node in sg.getChildren():
    print(node)

SoSeparatorsやSoGroupsといったこれらノードは自身の子ノードを持ちます。利用可能なCoinオブジェクトの全リストはCoin公式ドキュメントにあります。

今度はシーングラフに何か追加してみましょう。すてきな赤い立方体を追加してみることにしましょう:

col = coin.SoBaseColor()
col.rgb = (1,0,0)
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

(すてきな)赤い立方体ができました。以下を試してみてください:

col.rgb = (1, 1, 0)

わかったでしょうか?実行中であっても全てのものに対してアクセスと変更を行うことができるのです。再計算や再描画は必要ありません。Coinが全て面倒を見てくれます。物体のシーングラフへの追加、プロパティの変更、物体の非表示、一時的なオブジェクトの表示、何でもできます。もちろん3Dビューに関係したことだけですが。この表示はFreeCADがファイルを開いた時とオブジェクトが必要とした時に再計算されます。従って既存のFreeCADオブジェクトの外見を変更した場合、その変更はオブジェクトが再計算されるかファイルを再度開いた瞬間に失われます。

スクリプトでシーングラフを操作する場合の鍵となるのは必要な際に追加したノードの特定のプロパティにアクセスできるということなのです。例えば立方体を動かしたいとしましょう。自作のノードにSoTranslationノードを追加することになるでしょう。ちょうどこんな具合です:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
trans = coin.SoTranslation()
trans.translation.setValue([0,0,0])
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(trans)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

OpenInventorのシーングラフではその順番が重要であるということを思い出してください。ノードは以降のノードに影響を与えます。color red、cube、color yellow、sphere とすれば赤い立方体と黄色い球が表示されます。もし今、既存の自作ノードに移動を追加すると移動は立方体の後になり、立方体に影響を与えません。上記のように作成時に挿入しておけば次のようにできます:

trans.translation.setValue([2,0,0])

こうすると立方体が2単位分、右に移動します。 最後に何かを取り除くには次のようにします:

sg.removeChild(myCustomNode)

コールバック機能の使用

コールバック機能とはCoinライブラリの様な現在使用しているライブラリがコールバック、つまり現在実行中のPythonオブジェクトから特定の関数を呼び出すことを可能にするシステムのことです。これは非常に便利です。これを使うとシーンで何か特定のイベントが起きた場合にCoinからあなたへ通知することができるのです。Coinでは色々なものを監視することができます。マウスの位置、マウスボタンのクリック、キーボードのキーが押されたかどうか、まだまだ他にもあります。

FreeCADではそういったコールバックを簡単に使うための機能があります:

class ButtonTest:
    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick) 

    def getMouseClick(self,event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            print("Alert!!! A mouse button has been improperly clicked!!!")
            self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback) 
 
ButtonTest()

コールバックが起きた時にもオブジェクトは実行され続けなければならないのでコールバックはオブジェクトで初期化されなけれればなりません。 利用可能なイベントとパラメータの全リストまたはCoin公式ドキュメントを参照してください。

ドキュメント

残念ながらPivy自体にはちゃんとしたドキュメントがまだありません。しかしPivyはCoinと正確に対応するのでC++スタイルをPythonスタイルに読み替えれば(例えばSoFile::getClassTypeId()はPivyではSoFile.getClassId()となるでしょう)Coinドキュメントをリファレンスとして安全に使用できます。

In C++:

SoFile::getClassTypeId()

In Pivy

SoFile.getClassId()
Scenegraph
PySide