High Level 3 d Graphics Programming in Python
High Level 3 d Graphics Programming in Python
net/publication/341273053
CITATION READS
1 6,280
2 authors:
6 PUBLICATIONS 81 CITATIONS
Graz University of Technology
591 PUBLICATIONS 18,241 CITATIONS
SEE PROFILE
SEE PROFILE
All content following this page was uploaded by Tamer Fahmy on 09 May 2020.
General Information:
1. Introduction
1
Currently OpenGL is the primary choice for cross platform 3D graphics application development. OpenGL
provides so-called immediate mode access to the frame buffer where the application itself has to maintain the
data that describe the model.
OpenGL, designed as a low-level API, therefore provides no out of the box facilities for user interaction such
as moving objects to a different location or selecting them for further manipulations. Additional complicated
code needs to be implemented by the programmer to fulfill these tasks.
2 3 4
High-level libraries such as Open Inventor , Coin or Performer built on top of OpenGL have been
developed to facilitate and speed up the development process. They allow the creation of otherwise hard to
implement or involved 3D graphics applications.
Unlike OpenGL these libraries focus on creating 3D objects. Object information such as shape, size, location
in 3D space, is stored in a scene database. In contrast to OpenGL they provide the necessary functionality to
interact with objects and to change the objects in the scene.
Those libraries are referred to as operating in retained mode where all the data describing a model needs to
be specified in advance using predefined data structures. They internally organize the data in a hierarchical
database.
Another important distinction is made in this context between application- and data-driven scene graph
APIs. Data-driven toolkits only re-render when something changes in the scene, for example the user
changing the viewpoint of the scene. Application-driven toolkits re-render the scene continuously in an
application loop, using up all CPU resources available. The latter case is used for games and simulation
software such as flight simulators where high and constant frame rates are desirable. In general a data-driven
approach fits better for a general purpose 3D API where constant frame rate is not the main concern. More
importantly resources should be available for other computational tasks. Typical examples benefiting from
this approach are applications that visualize results of numerical simulations or 3D editors (level editor for
5
games). Examples of application-driven APIs are Performer or OpenSG , whereas Open Inventor or Coin
offer a data-driven API.
Performance is a key problem, hence these libraries are usually implemented in a compiled language such as
C++. However, the use of C++, a statically typed language with a heavy and complicated syntax, tends to be
error-prone and cumbersome. A dynamically typed and bound language with an intuitive syntax like Python
provides a more natural interface.
Consequently, bindings have been created to interface with those libraries in order to make them accessible
from within the Python interpreter allowing true Rapid Application Development. We are presenting the
6
benefits of using Python for high-level 3D graphics programming by presenting Pivy , a Python binding for
the popular object-oriented 3D C++ toolkit Open Inventor.
Open Inventor also defines a standard 3D file format (ASCII and binary) for scene data interchange. This
allows the construction of scene graphs in ASCII files without the need to program a single line. Those
ASCII files can then be viewed by using the provided viewers from Open Inventor or any common
modelling tool.
We chose to bind Pivy against Coin, which implements the SGI Open Inventor 2.1 API. Coin is portable over
a wide range of platforms (any UNIX / Linux / *BSD platform, all Microsoft Windows operating systems,
and Mac OS X) and adds additional features missing in the original SGI Open Inventor API such as
VRML97 support, 3D Sound, 3D Textures, Multi-threading and parallel rendering. Additionally GUI
bindings implementing viewer widgets for several GUI toolkits (Qt, Gtk, Xt, Cocoa, Win32) are available.
Coin is Open Source and has an active and growing community.
3. Pivy
3.1 Overview
Pivy is a Python binding for Coin where the interface is implemented using SWIG. Pivy allows:
As mentioned above, Open Inventor also features an extensible text-based file format. However, there is no
facility for procedural scripting. Pivy provides a powerful and easy-to-use scripting interface, unlike other
7 8
Open Inventor bindings such as those for Java and Scheme .
Additionally, existing C++ extensions can be easily wrapped using SWIG and used within Pivy. New Open
Inventor Nodes and NodeKits can also be developed solely in Python.
In the same fashion that Open Inventor allows C++ programmers to make use of direct OpenGL calls, the
9
same functionality is available for Python programmers through the existing PyOpenGL binding in Pivy.
4. A Pivy Example
The following code example creates a red Cone in a so-called 3D-model examination viewer:
from sogui import *
from pivy import *
import sys
def main():
# Initialize Coin. This returns a main window to use.
# If unsuccessful, exit.
myWindow = SoGui.init(sys.argv[0])
if myWindow == None: sys.exit(1)
myMaterial = SoMaterial()
myMaterial.diffuseColor(1.0, 0.0, 0.0) # Red
if __name__ == "__main__":
main()
First the sogui module which contains the classes and definitions relevant for the viewer is imported. In the
next line the pivy module is imported, which contains the actual Coin binding. In the main function
SoGui.init() initializes the Coin scene database and returns a widget. If SoQt (the Coin GUI binding for the
Qt toolkit) is used, a widget is returned that can be used from within PyQt (the Python binding for the Qt
toolkit). This allows Coin to be embedded in PyQt applications, similar to what can be done in C++ for Qt
applications. A material node is then created and its diffuse color field is set to red. An SoSeparator instance,
which represents the root node in the scene then gets two child nodes added: the newly created material node
and the SoCone shape node. The order in which the child nodes are added is important as the scene graph is
traversed from top to bottom and left to right. If we had reversed the order of the material and the cone node,
the cone would have been rendered in its default color as it is not affected by the material node. After this the
viewer instance is created, the window title is set and the viewer is displayed. Once the mainLoop() method
of the SoGui toolkit is called, the viewer appears and shows the rendered image.
The examination viewer allows manipulation of settings, such as the drawstyle of the object or viewing
position of the camera.
Alternatively the scene can be described using the Open Inventor file format by specifying it in a separate
file.
hellocone.iv contains:
#Inventor V2.1 ascii
Separator {
Material { diffuseColor 1 0 0 }
Cone {}
}
import sys
def main():
# Initialize Coin. This returns a main window to use.
# If unsuccessful, exit.
myWindow = SoGui.init(sys.argv[0])
if myWindow == None: sys.exit(1)
input = SoInput()
input.openFile("hellocone.iv")
if __name__ == "__main__":
main()
5. Conclusions
Pivy offers access to a powerful, easy to use and general purpose 3D graphics high-level API. Python
projects looking for an effective way to visualize their results in 3D, while simultaneously providing
interactive features out of the box, could benefit by its usage. Apart from scientific applications also games
could be easily developed using Pivy.
The combination of Coin and Pivy with its scripting node makes it useful for existing C++ Open Inventor
applications which are looking for a possibility to enhance their applications through a scripting facility.