Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • Python Tutorial
  • Interview Questions
  • Python Quiz
  • Python Glossary
  • Python Projects
  • Practice Python
  • Data Science With Python
  • Python Web Dev
  • DSA with Python
  • Python OOPs
Open In App
Next Article:
Animate image using OpenCV in Python
Next article icon

3D Modeling & Animation App Using Python

Last Updated : 09 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In recent times, Python has become widely recognized as a potent language for a variety of uses beyond the traditional realm of software development. One such domain is 3D modeling and animation, where Python's flexibility and user-friendly nature can be exploited to develop strong applications. This article will delve into the process of constructing a basic 3D modeling and animation application using Python, with a focus on the fundamental principles and libraries involved.

Setting Up and Designing the Application Environment

Before diving into coding, ensure you have Python installed on your system. Additionally, you'll need to install the following libraries:

  • PyOpenGL: A Python binding for OpenGL, providing access to OpenGL's full functionality.
  • PyQt5: A set of Python bindings for the Qt application framework, which will help us create a GUI for our application.
  • NumPy: Essential for numerical computing in Python, useful for handling vectors and matrices in 3D graphics.

You can install these libraries using pip:

pip install PyOpenGL PyQt5 numpy

Our application will have a basic interface with options to create and manipulate 3D objects. We'll use PyQt for creating the GUI and PyOpenGL for rendering the 3D graphics.

Setting Up the GUI

Let's start by creating a simple PyQt application window. Create a file named main.py and add the following code:

  • Set the geometry (position and size) of the main window using self.setGeometry(x, y, width, height).
  • Set the window title using self.setWindowTitle('Title').
  • Create a vertical layout (QVBoxLayout) named layout.
  • Create a central widget (QWidget) named central_widget and sets the layout (layout) for it.
  • Set central_widget as the central widget of the main window using self.setCentralWidget(central_widget).
Python
class MainWindow(QMainWindow):     def __init__(self):         super().__init__()         self.initUI()      def initUI(self):         self.setGeometry(100, 100, 800, 600)         self.setWindowTitle('3D Modeling & Animation App')          layout = QVBoxLayout()         central_widget = QWidget(self)         central_widget.setLayout(layout)         self.setCentralWidget(central_widget)          self.glWidget = GLWidget()         layout.addWidget(self.glWidget)          btn_create_object = QPushButton('Create Object', self)         btn_create_object.clicked.connect(self.create_object)         layout.addWidget(btn_create_object)          self.show()      def create_object(self):         print('Creating 3D object...')   if __name__ == '__main__':     app = QApplication(sys.argv)     mainWindow = MainWindow()     sys.exit(app.exec_()) 

Creating 3D Objects

Next, let's integrate PyOpenGL to render 3D graphics within our PyQt application. We'll extend our MainWindow class to include an OpenGL widget for rendering and also add functionality to create basic 3D objects using OpenGL primitives. We'll extend the GLWidget class to include methods for drawing objects.

Python
class GLWidget(QGLWidget):     def __init__(self, parent=None):         super().__init__(parent)         self.rotate_angle = 0         self.timer = self.startTimer(10)  # Timer for animation      def initializeGL(self):         pass      def resizeGL(self, width, height):         pass      def paintGL(self):         pass      def timerEvent(self, event):         pass 

1. initializeGL()

The initializeGL method provided is likely part of a class that deals with OpenGL programming, particularly for initializing the OpenGL context and setting up some initial parameters. Here’s what each part of the code does:

Python
def initializeGL(self):     glClearColor(0.0, 0.0, 0.0, 1.0)     glEnable(GL_DEPTH_TEST) 

1. glClearColor(0.0, 0.0, 0.0, 1.0):

  • Sets the color used to clear the framebuffer (the screen) before rendering. The parameters (0.0, 0.0, 0.0, 1.0) specify a black color ((R, G, B, A)), where R, G, and B are all 0.0 (indicating black), and A (alpha) is 1.0 (indicating fully opaque). This means that when the screen is cleared with glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), it will be filled with black.

2. glEnable(GL_DEPTH_TEST):

  • Enables depth testing in OpenGL. Depth testing is used to determine which objects are visible when they overlap (based on their depth or distance from the camera). Without depth testing enabled, objects may render incorrectly when they overlap in 3D space. Enabling depth testing ensures that closer objects obscure farther ones correctly.

2. resizeGL()

Python
    def resizeGL(self, width, height):         glViewport(0, 0, width, height)         glMatrixMode(GL_PROJECTION)         glLoadIdentity()         aspect_ratio = width / height         fov_degrees = 45.0         near_clip = 0.1         far_clip = 100.0          # Calculate perspective projection matrix manually         top = near_clip * math.tan(math.radians(fov_degrees / 2.0))         bottom = -top         left = bottom * aspect_ratio         right = top * aspect_ratio          glFrustum(left, right, bottom, top, near_clip, far_clip)         glMatrixMode(GL_MODELVIEW) 

The code snippet is a method definition within a class that likely deals with OpenGL programming, particularly for setting up the projection matrix during resizing of the OpenGL window. Let's break down what each part of the code does:

1. glViewport(0, 0, width, height):

  • Sets the viewport of the OpenGL window to cover the entire window area defined by width and height. This function determines how OpenGL maps its 2D coordinate system to the window's 2D pixel coordinates.

2. glMatrixMode(GL_PROJECTION):

  • Sets the current matrix mode to GL_PROJECTION, which means subsequent matrix operations (like transformations and projections) will affect the projection matrix stack.

3. glLoadIdentity():

  • Loads the identity matrix onto the current matrix stack (in this case, the projection matrix stack). This resets any previous transformations or projections applied to the projection matrix.

4. aspect_ratio = width / height :

  • Calculates the aspect ratio of the viewport, which is the ratio of width to height of the OpenGL window. This is crucial for maintaining correct perspective when rendering objects.

5. fov_degrees = 45.0 :

  • Specifies the field of view angle in degrees for the perspective projection. A higher angle (e.g., 90 degrees) would result in a wider field of view.

6. near_clip = 0.1 and far_clip = 100.0 :

  • Define the near and far clipping planes for the perspective projection. These determine the range of distances from the camera that objects are rendered. Objects closer than near_clip or farther than far_clip are clipped (not rendered).

7. Calculating the Frustum Parameters:

  • Computes the parameters (left, right, bottom, top) for the perspective projection using the glFrustum() function. This function constructs a perspective projection matrix based on these parameters and replaces the current projection matrix with it.

8. glFrustum(left, right, bottom, top, near_clip, far_clip):

  • Constructs a perspective projection matrix using the specified parameters (left, right, bottom, top, near_clip, far_clip). This projection matrix defines how OpenGL maps the 3D scene onto the 2D viewport.

9. glMatrixMode(GL_MODELVIEW):

  • Sets the current matrix mode back to GL_MODELVIEW, indicating that subsequent matrix operations (like transformations of objects) will affect the modelview matrix stack.

3. paintGL()

This Python code snippet is part of an OpenGL (Open Graphics Library) program using the PyOpenGL library, which is a Python binding for OpenGL. Here’s a breakdown of what the code does:

Python
    def paintGL(self):         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)         glLoadIdentity()         glTranslatef(0.0, 0.0, -5.0)         glRotatef(self.rotate_angle, 1, 1, 1)          glBegin(GL_QUADS)         glColor3f(1.0, 0.0, 0.0)  # Red         glVertex3f(1.0, 1.0, -1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(1.0, 1.0, 1.0)          glColor3f(0.0, 1.0, 0.0)  # Green         glVertex3f(1.0, -1.0, 1.0)         glVertex3f(-1.0, -1.0, 1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(1.0, -1.0, -1.0)          glColor3f(0.0, 0.0, 1.0)  # Blue         glVertex3f(1.0, 1.0, 1.0)         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(-1.0, -1.0, 1.0)         glVertex3f(1.0, -1.0, 1.0)          glColor3f(1.0, 1.0, 0.0)  # Yellow         glVertex3f(1.0, -1.0, -1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(1.0, 1.0, -1.0)          glColor3f(0.0, 1.0, 1.0)  # Cyan         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(-1.0, -1.0, 1.0)          glColor3f(1.0, 0.0, 1.0)  # Magenta         glVertex3f(1.0, 1.0, -1.0)         glVertex3f(1.0, 1.0, 1.0)         glVertex3f(1.0, -1.0, 1.0)         glVertex3f(1.0, -1.0, -1.0)         glEnd()          self.rotate_angle += 1 

1. Initialization and Clearing Buffers:

This line clears both the color buffer (`GL_COLOR_BUFFER_BIT`) and the depth buffer (`GL_DEPTH_BUFFER_BIT`), preparing the framebuffer for rendering a new frame.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

2. Loading Identity Matrix and Transformations:

  • glLoadIdentity() sets the current matrix to the identity matrix, which is a neutral transformation state.
  • glTranslatef(0.0, 0.0, -5.0) translates the scene along the z-axis by -5 units, effectively moving the rendered objects away from the viewer.
glLoadIdentity()
glTranslatef(0.0, 0.0, -5.0)

3. Rotation Transformation:

This line applies a rotation transformation to the scene. It rotates the scene around the axis that passes through (1, 1, 1) by an angle specified by self.rotate_angle. The rotation angle is incremented by 1 degree in each iteration of the paintGL() function.

glRotatef(self.rotate_angle, 1, 1, 1)

4. Rendering Quads:

Begins defining a series of quadrilateral faces.

Each glVertex3f call defines a vertex with its x, y, and z coordinates in 3D space. The color for each face is set using glColor3f.

  • Red Face (top face)
  • Green Face (bottom face)
  • Blue Face (front face)
  • Yellow Face (back face)
  • Cyan Face (left face)
  • Magenta Face (right face)

These faces together form a cube in 3D space.

glBegin(GL_QUADS)

5. Ending Quad Definition:

Ends the definition of the quadrilateral faces.

glEnd()

6. Incrementing Rotation Angle

This line increments the rotation angle by 1 degree in each call to paintGL(), causing the cube to rotate continuously.

self.rotate_angle += 1

4. TimerEvent()

  • timerEvent is a method that is called when a timer event occurs (e.g., after a specified time interval).
  • self.update() is called to update the UI elements of GLWidget based on the timer event.
Python
    def timerEvent(self, event):         self.update() 

Complete Code

Python
import sys import math from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton from PyQt5.QtOpenGL import QGLWidget from OpenGL.GL import *   class GLWidget(QGLWidget):     def __init__(self, parent=None):         super().__init__(parent)         self.rotate_angle = 0         self.timer = self.startTimer(10)  # Timer for animation      def initializeGL(self):         glClearColor(0.0, 0.0, 0.0, 1.0)         glEnable(GL_DEPTH_TEST)      def resizeGL(self, width, height):         glViewport(0, 0, width, height)         glMatrixMode(GL_PROJECTION)         glLoadIdentity()         aspect_ratio = width / height         fov_degrees = 45.0         near_clip = 0.1         far_clip = 100.0          # Calculate perspective projection matrix manually         top = near_clip * math.tan(math.radians(fov_degrees / 2.0))         bottom = -top         left = bottom * aspect_ratio         right = top * aspect_ratio          glFrustum(left, right, bottom, top, near_clip, far_clip)         glMatrixMode(GL_MODELVIEW)      def paintGL(self):         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)         glLoadIdentity()         glTranslatef(0.0, 0.0, -5.0)         glRotatef(self.rotate_angle, 1, 1, 1)          glBegin(GL_QUADS)         glColor3f(1.0, 0.0, 0.0)  # Red         glVertex3f(1.0, 1.0, -1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(1.0, 1.0, 1.0)          glColor3f(0.0, 1.0, 0.0)  # Green         glVertex3f(1.0, -1.0, 1.0)         glVertex3f(-1.0, -1.0, 1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(1.0, -1.0, -1.0)          glColor3f(0.0, 0.0, 1.0)  # Blue         glVertex3f(1.0, 1.0, 1.0)         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(-1.0, -1.0, 1.0)         glVertex3f(1.0, -1.0, 1.0)          glColor3f(1.0, 1.0, 0.0)  # Yellow         glVertex3f(1.0, -1.0, -1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(1.0, 1.0, -1.0)          glColor3f(0.0, 1.0, 1.0)  # Cyan         glVertex3f(-1.0, 1.0, 1.0)         glVertex3f(-1.0, 1.0, -1.0)         glVertex3f(-1.0, -1.0, -1.0)         glVertex3f(-1.0, -1.0, 1.0)          glColor3f(1.0, 0.0, 1.0)  # Magenta         glVertex3f(1.0, 1.0, -1.0)         glVertex3f(1.0, 1.0, 1.0)         glVertex3f(1.0, -1.0, 1.0)         glVertex3f(1.0, -1.0, -1.0)         glEnd()          self.rotate_angle += 1      def timerEvent(self, event):         self.update()   class MainWindow(QMainWindow):     def __init__(self):         super().__init__()         self.initUI()      def initUI(self):         self.setGeometry(100, 100, 800, 600)         self.setWindowTitle('3D Modeling & Animation App')          layout = QVBoxLayout()         central_widget = QWidget(self)         central_widget.setLayout(layout)         self.setCentralWidget(central_widget)          self.glWidget = GLWidget()         layout.addWidget(self.glWidget)          btn_create_object = QPushButton('Create Object', self)         btn_create_object.clicked.connect(self.create_object)         layout.addWidget(btn_create_object)          self.show()      def create_object(self):         print('Creating 3D object...')   if __name__ == '__main__':     app = QApplication(sys.argv)     mainWindow = MainWindow()     sys.exit(app.exec_()) 

Output

Conclusion:

This article is a simple introduction to creating a 3D modeling and animation app using Python, PyQt, and PyOpenGL. We started by setting up a basic PyQt application window and then integrated OpenGL for rendering 3D graphics. Although this example focused on creating a static 3D object (a cube), you can build upon it by adding features for object manipulation, animation, lighting effects, and more. The flexibility of Python and the wide-ranging capabilities of OpenGL make them an exciting combination for developing advanced 3D applications.


Next Article
Animate image using OpenCV in Python
author
kamran1bkza
Improve
Article Tags :
  • Python
  • Python-PyQt
  • PyQt-exercise
  • OpenAI API
Practice Tags :
  • python

Similar Reads

  • Python | Animation in Kivy using .kv file
    Kivy is a platform independent GUI tool in Python. As it can be run on Android, IOS, Linux, and Windows, etc. It is basically used to develop the Android application, but it does not mean that it can not be used on Desktops applications. Animation: Animation and AnimationTransition are used to anima
    3 min read
  • GUI Automation using Python
    In this article, we will explore how we can do GUI automation using Python. There are many modules that can do these things, but in this article, we will use a module named PyAutoGUI to perform GUI and desktop automation using python.  We would explore two sections - How to automatically use the mou
    12 min read
  • Animate image using OpenCV in Python
    In this article, we will discuss how to animate an image using python's OpenCV module. Let's suppose we have one image. Using that single image we will animate it in such a way it will appear continuous array of the same image. This is useful in animating the background in certain games. For example
    3 min read
  • How to animate 3D Graph using Matplotlib?
    Prerequisites: Matplotlib, NumPy Graphical representations are always easy to understand and are adopted and preferable before any written or verbal communication. With Matplotlib we can draw different types of Graphical data. In this article, we will try to understand, How can we create a beautiful
    4 min read
  • 3D Contour Plotting in Python using Matplotlib
    Matplotlib was introduced keeping in mind, only two-dimensional plotting. But at the time when the release of 1.0 occurred, the 3d utilities were developed upon the 2d and thus, we have 3d implementation of data available today! The 3d plots are enabled by importing the mplot3d toolkit. Let's look a
    2 min read
  • Create an Animated GIF Using Python Matplotlib
    In this article, we will discuss how to create an animated GIF using Matplotlib in Python. Matplotlib can be used to create mathematics-based animations only. These can include a point moving on the circumference of the circle or a sine or cosine wave which are just like sound waves. In Matplotlib w
    3 min read
  • How to Create Animations in Python?
    Animations are a great way to make Visualizations more attractive and user-appealing. It helps us to demonstrate Data Visualization in a Meaningful Way. Python helps us to create Animation Visualization using existing powerful Python libraries. Matplotlib is a very popular Data Visualisation Library
    5 min read
  • 3D Wireframe plotting in Python using Matplotlib
    To create static, animated and interactive visualizations of data, we use the Matplotlib module in Python. The below programs will depict 3D wireframe. visualization of data in Python. In-order to visualize data using 3D wireframe we require some modules from matplotlib, mpl_toolkits and numpy libra
    1 min read
  • MoviePy – Creating Animation Using Matplotlib
    In this article we will see how we create animations in MoviePy using matplotlib. MoviePy is a Python module for video editing, which can be used for basic operations on videos and GIF’s. Video is formed by the frames, combination of frames creates a video each frame is an individual image. Matplotl
    3 min read
  • 3D Line Plots using Plotly in Python
    Plotly is a Python library that is used to design graphs, especially interactive graphs. It can plot various graphs and charts like histogram, barplot, boxplot, spreadplot and many more. It is mainly used in data analysis as well as financial analysis. plotly is an interactive visualization library
    2 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences