TheHubbit / PyInventor

3D Graphics in Python with Open Inventor
http://thehubbit.github.io/PyInventor
BSD 3-Clause "New" or "Revised" License
16 stars 8 forks source link

How to work with iv.Gate: no input, no output #7

Closed InventorMentor closed 7 years ago

InventorMentor commented 7 years ago

Hi Thomas,

You may want to include the following "examiner_embed.py" example from Tamer Fahmy's Pivy to PyInventor's example suite. My port of this example to PyInventor "almost" works :-) but apparently the iv.Gate toggeling the rotation of the cone was created incompletely by myself (SoGate for an MFFloat in the original) and unfortunately does not provide both required fields "input" and "output". Could you please make a suggestion how I can work with iv.Gate? Many thanks in advance!

Best, Peter

""" Demonstrates embedding of an ExaminerViewer
within a simple widget hierarchy. """

import sys
from random import random
from PySide.QtCore import *
from PySide.QtGui import *
from PySide import QtOpenGL
from PyInventor import QtInventor
import inventor as iv

class ExaminerViewer(QWidget):
    """ExaminerViewer style QtGui widget"""

    myCamera = None

    def __init__(self, parent=None, title="Examiner Viewer", scene=None,
                 headlight=True, camera=True, interaction=False,
                 backgroundColor = (0.0, 0.0, 0.0)):

        QWidget.__init__(self, parent)

        self.ivWidget = QtInventor.QIVWidget(format=QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers))
        self.ivWidget.sceneManager.background = backgroundColor

        # create a superscene containing a headlight and
        # an examiner viewer style camera
        examinerStyleCamera = iv.Separator()
        if headlight:
            examinerStyleCamera += iv.DirectionalLight()
        if camera:
            self.myCamera = iv.PerspectiveCamera()
            examinerStyleCamera += self.myCamera
        self.superScene = examinerStyleCamera
        self.superScene += scene

        self.ivWidget.sceneManager.scene = self.superScene       
        self.ivWidget.sceneManager.view_all()
        if interaction:
            self.ivWidget.sceneManager.interaction(0)
        else:
            self.ivWidget.sceneManager.interaction(1)       

        mainLayout = QHBoxLayout()
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.addWidget(self.ivWidget)
        self.setLayout(mainLayout)
        self.setWindowTitle(title)

    def minimumSizeHint(self):
        return QSize(100, 100)

class EmbeddedWindow(QMainWindow):
    def __init__(self, *args):
        super(self.__class__, self).__init__()

        # construct a simple scenegraph
        root = iv.Separator()
        self.rotxyz = iv.RotationXYZ()
        self.gate = iv.Gate("MFFloat") # iv.Gate(SoMFFloat.getClassTypeId())
        self.elapsedTime = iv.ElapsedTime()
        self.gate.enableNotify(False)
        self.gate.connect("input", self.elapsedTime, "timeOut")
        self.rotxyz.connect("angle", self.gate, "output")
        self.material = iv.Material()
        self.material.diffuseColor = (0.0, 1.0, 1.0)
        self.cone = iv.Cone()
        root += self.rotxyz
        root += self.material
        root += self.cone

        # dummy widget needed for the PyQt stuff
        self.centralWidget = QWidget(self)
        self.mainLayout = QVBoxLayout(self.centralWidget)
        self.examiner = ExaminerViewer(parent=self.centralWidget, scene=root)
        self.mainLayout.addWidget(self.examiner) # add the examiner viewer
        self.hLayout = QHBoxLayout()
        self.groupBox = QGroupBox("Choose axis", self.centralWidget)
        self.hboxlayout1 = QHBoxLayout(self.groupBox)
        self.buttonGroup = QButtonGroup(self.groupBox)
        self.radio_x = QRadioButton("&X", self.groupBox)
        self.radio_y = QRadioButton("&Y", self.groupBox)
        self.radio_z = QRadioButton("&Z", self.groupBox)
        self.buttonGroup.addButton(self.radio_x, 0)
        self.buttonGroup.addButton(self.radio_y, 1)
        self.buttonGroup.addButton(self.radio_z, 2)
        self.hboxlayout1.addWidget(self.radio_x)
        self.hboxlayout1.addWidget(self.radio_y)
        self.hboxlayout1.addWidget(self.radio_z)
        self.hLayout.addWidget(self.groupBox)

        self.controlLayout = QVBoxLayout()
        self.checkbox = QCheckBox("Enable &rotation", self.centralWidget)
        self.checkbox.setDown(False)
        self.button = QPushButton("&Change cone color", self.centralWidget)
        self.controlLayout.addWidget(self.checkbox)
        self.controlLayout.addWidget(self.button)

        self.hLayout.addLayout(self.controlLayout)
        self.mainLayout.addLayout(self.hLayout)

        self.setCentralWidget(self.centralWidget)

        self.radio_x.setChecked(True)

        self.examiner.show()

        self.connect(self.buttonGroup, SIGNAL("buttonClicked(int)"), self.change_axis)
        self.connect(self.button, SIGNAL("clicked()"), self.change_color)
        self.connect(self.checkbox, SIGNAL("clicked()"), self.rotate)

    def change_axis(self, axis):
        self.rotxyz.axis = axis

    def change_color(self):
        self.material.diffuseColor = (random(), random(), random())

    def rotate(self):
        self.gate.enableNotify(not self.gate.enableNotify(False))

def main():
    # Initialize Qt. This returns a main window to use.
    # If unsuccessful, exit.
    app = QApplication(sys.argv)

    if app is None:
        sys.exit(1)

    # set up scrollview window
    vp = EmbeddedWindow(app)
    vp.setWindowTitle("Embedded viewer")
    # map window
    vp.resize(640, 480)

    # set termination condition
    QObject.connect(qApp, SIGNAL("lastWindowClosed()"), qApp, SLOT("quit()"))

    # start event loop
    # show the widget
    vp.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
TheHubbit commented 7 years ago

Hi Peter,Thanks for the example! I added and linked a page in the wiki for user examples (only your's for now). Feel free to edit or enhance if needed. Regards,Thomas

On Friday, March 24, 2017 12:27 AM, InventorMentor <notifications@github.com> wrote:

Hi Thomas,You may want to include the following "examiner_embed.py" example from Tamer Fahmy's Pivy to PyInventor's example suite. My port of this example to PyInventor "almost" works :-) but apparently the iv.Gate toggeling the rotation of the cone was created incompletely by myself (SoGate for an MFFloat in the original) and unfortunately does not provide both required fields "input" and "output". Could you please make a suggestion how I can work with iv.Gate? Many thanks in advance!Best, Peter""" Demonstrates embedding of an ExaminerViewer within a simple widget hierarchy. """

import sys from random import random from PySide.QtCore import from PySide.QtGui import from PySide import QtOpenGL from PyInventor import QtInventor import inventor as iv

class ExaminerViewer(QWidget): """ExaminerViewer style QtGui widget"""

myCamera = None

def __init__(self, parent=None, title="Examiner Viewer", scene=None,
             headlight=True, camera=True, interaction=False,
             backgroundColor = (0.0, 0.0, 0.0)):

    QWidget.__init__(self, parent)

    self.ivWidget = QtInventor.QIVWidget(format=QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers))
    self.ivWidget.sceneManager.background = backgroundColor

    # create a superscene containing a headlight and
    # an examiner viewer style camera
    examinerStyleCamera = iv.Separator()
    if headlight:
        examinerStyleCamera += iv.DirectionalLight()
    if camera:
        self.myCamera = iv.PerspectiveCamera()
        examinerStyleCamera += self.myCamera
    self.superScene = examinerStyleCamera
    self.superScene += scene

    self.ivWidget.sceneManager.scene = self.superScene       
    self.ivWidget.sceneManager.view_all()
    if interaction:
        self.ivWidget.sceneManager.interaction(0)
    else:
        self.ivWidget.sceneManager.interaction(1)       

    mainLayout = QHBoxLayout()
    mainLayout.setContentsMargins(0, 0, 0, 0)
    mainLayout.addWidget(self.ivWidget)
    self.setLayout(mainLayout)
    self.setWindowTitle(title)

def minimumSizeHint(self):
    return QSize(100, 100)

class EmbeddedWindow(QMainWindow): def init(self, *args): super(self.class, self).init()

    # construct a simple scenegraph
    root = iv.Separator()
    self.rotxyz = iv.RotationXYZ()
    self.gate = iv.Gate("MFFloat") # iv.Gate(SoMFFloat.getClassTypeId())
    self.elapsedTime = iv.ElapsedTime()
    self.gate.enableNotify(False)
    self.gate.connect("input", self.elapsedTime, "timeOut")
    self.rotxyz.connect("angle", self.gate, "output")
    self.material = iv.Material()
    self.material.diffuseColor = (0.0, 1.0, 1.0)
    self.cone = iv.Cone()
    root += self.rotxyz
    root += self.material
    root += self.cone

    # dummy widget needed for the PyQt stuff
    self.centralWidget = QWidget(self)
    self.mainLayout = QVBoxLayout(self.centralWidget)
    self.examiner = ExaminerViewer(parent=self.centralWidget, scene=root)
    self.mainLayout.addWidget(self.examiner) # add the examiner viewer
    self.hLayout = QHBoxLayout()
    self.groupBox = QGroupBox("Choose axis", self.centralWidget)
    self.hboxlayout1 = QHBoxLayout(self.groupBox)
    self.buttonGroup = QButtonGroup(self.groupBox)
    self.radio_x = QRadioButton("&X", self.groupBox)
    self.radio_y = QRadioButton("&Y", self.groupBox)
    self.radio_z = QRadioButton("&Z", self.groupBox)
    self.buttonGroup.addButton(self.radio_x, 0)
    self.buttonGroup.addButton(self.radio_y, 1)
    self.buttonGroup.addButton(self.radio_z, 2)
    self.hboxlayout1.addWidget(self.radio_x)
    self.hboxlayout1.addWidget(self.radio_y)
    self.hboxlayout1.addWidget(self.radio_z)
    self.hLayout.addWidget(self.groupBox)

    self.controlLayout = QVBoxLayout()
    self.checkbox = QCheckBox("Enable &rotation", self.centralWidget)
    self.checkbox.setDown(False)
    self.button = QPushButton("&Change cone color", self.centralWidget)
    self.controlLayout.addWidget(self.checkbox)
    self.controlLayout.addWidget(self.button)

    self.hLayout.addLayout(self.controlLayout)
    self.mainLayout.addLayout(self.hLayout)

    self.setCentralWidget(self.centralWidget)

    self.radio_x.setChecked(True)

    self.examiner.show()

    self.connect(self.buttonGroup, SIGNAL("buttonClicked(int)"), self.change_axis)
    self.connect(self.button, SIGNAL("clicked()"), self.change_color)
    self.connect(self.checkbox, SIGNAL("clicked()"), self.rotate)

def change_axis(self, axis):
    self.rotxyz.axis = axis

def change_color(self):
    self.material.diffuseColor = (random(), random(), random())

def rotate(self):
    self.gate.enableNotify(not self.gate.enableNotify(False))

def main():

Initialize Qt. This returns a main window to use.

# If unsuccessful, exit.
app = QApplication(sys.argv)

if app is None:
    sys.exit(1)

# set up scrollview window
vp = EmbeddedWindow(app)
vp.setWindowTitle("Embedded viewer")
# map window
vp.resize(640, 480)

# set termination condition
QObject.connect(qApp, SIGNAL("lastWindowClosed()"), qApp, SLOT("quit()"))

# start event loop
# show the widget
vp.show()
sys.exit(app.exec_())

if name == 'main': main()

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

TheHubbit commented 7 years ago

Hi Peter, The engines Gate, SelectOne and Concatenate require a type to be passed to the constructor. I just added support for those types to the scene object initialization functions. You can now construct those types by passing the field data type as an argument. For example:

import inventor as iv

gate = iv.Gate('MFFloat')
concatenate = iv.Concatenate('MFString')
selectone = iv.SelectOne('MFFloat')