Interface with QPanda3D (script who use Render Pipeline)

Hello everyone,

I’ve been interested in Panda3D for a while, I plan to take the plunge now.

I’m going to have lots of questions to ask about Panda3D.

I’m using (I’m a complete beginner, sorry) for now I’m building a little Python script (version 3) that uses the Render Pipeline. I would like to interface with QPanda3D but I can’t, can you help me?

from panda3d.core import load_prc_file_data
from direct.showbase.ShowBase import ShowBase

from rpcore import RenderPipeline

#from direct.gui.OnscreenText import OnscreenText

class Application(ShowBase):

    def __init__(self) :
        #ShowBase.__init__(self)
        
        # Résolution
        # Titre de la fenêtre
        load_prc_file_data("", """
            win-size 1600 900
            window-title Essai
        """)
        
        self.posZ_modele = -0.7
        self.posZ_camera = 0.7

        self.render_pipeline = RenderPipeline()
        self.render_pipeline.create(self)

        self.render_pipeline.daytime_mgr.time = "17:30"
        
        model = self.loader.load_model("salle_expo_001.bam")
        model.reparent_to(self.render)

        self.render_pipeline.prepare_scene(model)

        model.setScale(1, 1, 1)
        
        self.x = 0
        self.y = 0
        self.z = self.posZ_camera
        
        model.setPos(self.x, self.y, self.posZ_modele)
        
        #base.disableMouse()
        
        base.camera.setPos(0, 0, self.posZ_camera)
        base.camLens.setFov(102)
        
Application().run()

Thanks in advance.

First of all, welcome to the forum! I hope that you enjoy your time here! :slight_smile:

I’ve never used QPanda3D (that I recall) myself, but based on a quick search it looks like it may have its own classes from which you’re expected to inherit in place of the baseline Panda3D classes such as ShowBase.

It might be worth looking to QPanda3D’s documentation for a tutorial, or example code, perhaps.

Hello Thaumaturge,

This works by loading the standard (panda) model but I can’t adapt it for Render Pipeline use.

Well, it looks like the “Panda3DWorld” class inherits from the “ShowBase” class, so I would imagine that you would pass your instance of the former to RenderPipeline’s “create” method–i.e. that it would work just as in the code that you gave in the first post.

What precisely is the issue that you’re encountering in applying RenderPipeline to the example in your post just above this one? Knowing what’s going wrong, or where you’re stuck, might give me some direction in offering suggestions.

That said, do note that I don’t use RenderPipeline myself, so I may end up bowing out in favour of awaiting another forum-member who knows it better.

Thaumaturge I adapted a very simple exemple here :

from QPanda3D.Panda3DWorld import Panda3DWorld
from QPanda3D.QPanda3DWidget import QPanda3DWidget
# import PyQt5 stuff
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys

#from panda3d.core import Point3, Vec3, Vec4, VBase4
#from direct.interval.LerpInterval import LerpHprInterval
#from direct.interval.IntervalGlobal import *

from direct.gui.OnscreenImage import OnscreenImage

from rpcore import RenderPipeline ################

class PandaTest(Panda3DWorld):
    '''
    This is the class that defines our world
    It inherits from Panda3DWorld that inherits from 
    Panda3D's ShowBase class
    '''
    def __init__(self):
        Panda3DWorld.__init__(self)
        
        self.render_pipeline = RenderPipeline() ###########
        self.render_pipeline.create(self) #############
        
        #self.win.setClearColorActive(True)
        #self.win.setClearColor(VBase4(0, 0.5, 0, 1))
        
        self.render_pipeline = RenderPipeline() ###########
        self.render_pipeline.create(self) ###########

        self.render_pipeline.daytime_mgr.time = "17:30" ###########
        
        model = self.loader.load_model("salle_expo_001.bam") ###########
        model.reparent_to(self.render) ###########

        self.render_pipeline.prepare_scene(model) ###########

        model.setScale(1, 1, 1) ###########
        
        self.x = 0 ###########
        self.y = 0 ###########
        self.z = self.posZ_camera ###########
        
        model.setPos(self.x, self.y, self.posZ_modele) ###########
        
        self.cam.setPos(0, 0, self.posZ_camera) ###########
        self.cam.setFov(102) ###########


if __name__ == "__main__":    
    world = PandaTest() 
    
    app = QApplication(sys.argv)
    appw=QMainWindow()
    appw.setGeometry(50, 50, 800, 600)

    pandaWidget = QPanda3DWidget(world)
    appw.setCentralWidget(pandaWidget)
    appw.show()
    
    sys.exit(app.exec_())

… and this is the error I get:

(panda3d_py_3_7) angelo@angelo-kubuntu:~/Documents/Python/Panda3D$ python qpanda_world.py
[>] CORE                      rpcore.native imported 
[>] CORE                      Using panda3d-supplied core module 
Known pipe types:
  glxGraphicsPipe
(1 aux display modules not yet loaded.)
[>] RenderPipeline            Using Python 3.7 with architecture linux_amd64 
[>] RenderPipeline            Using Panda3D 1.10.11 built on Jan  7 2022 09:44:03 
[>] RenderPipeline            Using git commit d66ef59ecc0ca1078e2dc9629984f9d08bfee806 
[>] MountManager              Auto-Detected base path to /home/angelo/miniconda3/envs/panda3d_py_3_7/lib/python3.7/site-packages 

[!!!] RenderPipeline          You constructed your own ShowBase object but you
did not call pre_show_base_init() on the render
pipeline object before! Checkout the 00-Loading the
pipeline sample to see how to initialize the RP.

[>] MountManager              Cleaning up .. 

Ah, I see!

Looking over at one of the samples for RenderPipeline, I see that it specifically notes that one isn’t supposed to call the constructor for ShowBase, as RenderPipeline does this itself.

I thus looked at the code for RenderPipeline, and specifically, what it does and what its comments instruct in its “create” and “_init_showbase” methods (the latter being called by the former). Based on this, it seems that what you want to do can be done if you simply construct RenderPipeline and then call its “pre_showbase_init” method all before calling the constructor for ShowBase–or in this case, “Panda3DWorld”.

Something like this, I think:

class PandaTest(Panda3DWorld)
    def __init__(self):
        self.render_pipeline = RenderPipeline()
        self.render_pipeline.pre_showbase_init()

        Panda3DWorld.__init__(self)

        self.render_pipeline.create(self)

        # The rest of your code then follows...

Hello Thaumaturge,

Thank you for your details.

I tried but in fact the scene does not appear in the container. Here is my code:

import sys

from rpcore import RenderPipeline

from direct.gui.OnscreenText import OnscreenText

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from QPanda3D.QMouseWatcherNode import QMouseWatcherNode

from QPanda3D.QPanda3DWidget import QPanda3DWidget
from QPanda3D.Panda3DWorld import Panda3DWorld

class Application(Panda3DWorld):

    def __init__(self) :
        
        self.render_pipeline = RenderPipeline()
        self.render_pipeline.pre_showbase_init()

        Panda3DWorld.__init__(self)

        self.render_pipeline.create(self)
        
        self.render_pipeline.daytime_mgr.time = "17:30"

        model = self.loader.load_model("salle_expo_001.bam")
        model.reparent_to(self.render)

        self.render_pipeline.prepare_scene(model)

        model.setScale(1, 1, 1)
        
        #base.disableMouse()
        
        model.setPos(0, 0, -0.7)
        
        base.camera.setPos(0, 0, 0.7)
        base.camLens.setFov(102)
       
if __name__ == "__main__":

    world = Application()

    app = QApplication(sys.argv)
    appw = QMainWindow()
    appw.setGeometry(50, 50, 1600, 900)
    
    appw.setWindowTitle('Test Panda3DWorld/QPanda3DWidget')
    
    main_widget = QWidget()
    main_widget.setLayout(QVBoxLayout())

    pandaWidget = QPanda3DWidget(world)

    btn_widget = QWidget()
    btn_widget.setMaximumHeight(50)
    btn_widget.setLayout(QHBoxLayout())

    main_widget.layout().addWidget(pandaWidget)
    main_widget.layout().addWidget(btn_widget)

    btn_jump = QPushButton("Bout 1")
    btn_widget.layout().addWidget(btn_jump)
    #btn_jump.clicked.connect(world.jump)

    btn_roll = QPushButton("Bout 2")
    btn_widget.layout().addWidget(btn_roll)
    #btn_roll.clicked.connect(world.roll)

    appw.setCentralWidget(main_widget)
    appw.show()
    sys.exit(app.exec_())

Here is the window.

That, I’m afraid, I don’t know about–I use neither QT (let alone QPanda3D) nor RenderPipeline, so I’m not at all familiar with getting them to interoperate.

At this point I think that I’ll bow out in favour of another forum-member hopefully chiming in, with my apologies!

It doesn’t matter, you’ve already helped me a lot!, It’s very nice of you.

Just for clarification if I replace QPanda3DWorld with ShowBase (with exactly the same code), the scene appears for a while then disappears with the error:

(panda3d_py_3_7) angelo@angelo-kubuntu:~/Documents/Python/Panda3D$ python ess_qpanda_world_002.py 
[>] CORE                      rpcore.native imported 
[>] CORE                      Using panda3d-supplied core module 
[>] RenderPipeline            Using Python 3.7 with architecture linux_amd64 
[>] RenderPipeline            Using Panda3D 1.10.11 built on Jan  7 2022 09:44:03 
[>] RenderPipeline            Using git commit d66ef59ecc0ca1078e2dc9629984f9d08bfee806 
[>] MountManager              Auto-Detected base path to /home/angelo/miniconda3/envs/panda3d_py_3_7/lib/python3.7/site-packages 
[>] RenderPipeline            Mount manager was not mounted, mounting now ... 
[>] MountManager              Setting up virtual filesystem 
[>] MountManager              Mounting auto-detected config dir: /home/angelo/miniconda3/envs/panda3d_py_3_7/lib/python3.7/site-packages/config/ 
[>] MountManager              Mounting ramdisk as /$$rptemp 
[>] RenderPipeline            No settings loaded, loading from default location 
Known pipe types:
  glxGraphicsPipe
(1 aux display modules not yet loaded.)
[>] RenderPipeline            Driver Version = 4.3.0 NVIDIA 390.151 
[>] RenderPipeline            Driver Vendor = NVIDIA Corporation 
[>] RenderPipeline            Driver Renderer = GeForce GTX 1070/PCIe/SSE2 
[>] RenderPipeline            Render resolution is 800 x 600 
[>] LightManager              Tile size = 24 x 16 , Num tiles = 34 x 38 
[>] GPUCommandQueue           Allocating command buffer of size 32768 
[>] GroupedInputBlock         Native UBO support = False 
[!] RPLoader                  Loading '/$$rp/data/default_cubemap/cubemap.txo' took 309.05 ms
[!] RPLoader                  Loading '/$$rp/data/builtin_models/skybox/skybox.txo' took 112.16 ms
[>] PluginManager             Loading plugin settings 
[>] PluginManager             Creating plugin instances .. 
[>] Debugger                  Creating debugger 
[>] plugin:scattering         Loading scattering method for 'eric_bruneton' 
[>] StageManager              Setup stages .. 
[>] StageManager              Preparing stages .. 
[>] AOStage                   Blur quality is MEDIUM 
[>] StageManager              Awaiting future pipe Exposure 
[>] UpdatePreviousPipesStage  Creating previous pipes stage .. 
[>] StageManager              Writing shader config 
[!] RPLoader                  Loading '/$$rp/rpplugins/bloom/resources/lens_dirt.txo' took 114.6 ms
[>] plugin:pssm               Initializing pssm .. 
[>] ScatteringMethodEricBruneton Precomputing ... 
[>] RenderPipeline            Finished initialization in 1.453 s, first frame: 3 
Traceback (most recent call last):
  File "ess_qpanda_world_002.py", line 80, in <module>
    pandaWidget = QPanda3DWidget(world)
  File "/home/angelo/miniconda3/envs/panda3d_py_3_7/lib/python3.7/site-packages/QPanda3D/QPanda3DWidget.py", line 72, in __init__
    self.panda3DWorld.set_parent(self)
AttributeError: 'Application' object has no attribute 'set_parent'
[>] MountManager              Cleaning up ..

I’m afraid I’ll have to use Direct.Gui with the RenderPipeline first.

Do you know if there are QPanda3D developers here on the forums?

1 Like

It’s my pleasure; I’m glad to have helped. :slight_smile:

I’m afraid that I don’t know, alas. That doesn’t mean that there are none, however!

:+1:

I’m going to have other questions more specific to Panda3D. I will open other threads regarding this. I still need to make some progress in my project. :slightly_smiling_face:

1 Like