I am creating a gui in python using OpenGL and PyQt5. I'm struggling to get the plotting order correct in a gui I'm making. I am trying to get 3d points to show up on top of the mesh faces, but nothing I do gets the mesh transparency to change, or adds the 3d points on top of the mesh.

Here, you can see my gui with the mesh person in white, and some red dots around the waist. I can't get them to appear on top of the mesh.
This is my code:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QHBoxLayout, QSizePolicy
from PyQt5.QtCore import Qt # Import Qt module for alignment
import pyqtgraph.opengl as gl
import numpy as np
def read_obj_file(file_path):
"""
Read vertices and faces from an OBJ file.
"""
vertices = []
faces = []
with open(file_path, 'r') as f:
for line in f:
parts = line.strip().split()
if len(parts) == 0 or parts[0] == '#':
continue
if parts[0] == 'v':
vertices.append(list(map(float, parts[1:])))
elif parts[0] == 'f':
face = []
for vertex in parts[1:]:
indices = vertex.split('/')
face.append(int(indices[0]) - 1) # OBJ file indices are 1-based
faces.append(face)
return np.array(vertices), np.array(faces)
def triangulate_faces(faces):
"""
Triangulate the quadrilateral faces into triangles.
"""
triangles = []
for face in faces:
# Split each quadrilateral face into two triangles
triangles.append([face[0], face[1], face[2]])
triangles.append([face[0], face[2], face[3]])
return np.array(triangles)
def create_mesh(vertices, faces):
mesh = gl.GLMeshItem(vertexes=vertices, faces=faces, drawEdges=True)
#how to make edge thickness bigger??
return mesh
def plane_mesh_intersection(vertices, faces, y_plane):
"""
Find the intersection points of a plane in the y-direction with a mesh.
Args:
- vertices (np.array): Array of mesh vertices.
- faces (np.array): Array of mesh faces.
- y_plane (float): Y-coordinate of the plane.
Returns:
- intersection_points (list): List of intersection points as (x, y, z) coordinates.
"""
intersection_points = []
for face in faces:
v1, v2, v3 = vertices[face[0]], vertices[face[1]], vertices[face[2]]
# Check if all vertices are on the same side of the plane
above_plane = v1[1] >= y_plane and v2[1] >= y_plane and v3[1] >= y_plane
below_plane = v1[1] < y_plane and v2[1] < y_plane and v3[1] < y_plane
if not above_plane and not below_plane:
# Calculate intersection points with the plane for each edge
intersections = []
for v_start, v_end in [(v1, v2), (v2, v3), (v3, v1)]:
# Check if the edge crosses the plane
if v_start[1] != v_end[1]:
t = (y_plane - v_start[1]) / (v_end[1] - v_start[1])
if 0 <= t <= 1:
intersection_point = (
v_start[0] + t * (v_end[0] - v_start[0]),
y_plane,
v_start[2] + t * (v_end[2] - v_start[2])
)
intersections.append(intersection_point)
# Add intersection points to the list
if intersections:
intersection_points.extend(intersections)
return intersection_points
def main():
# Create a PyQtGraph application
app = QApplication(sys.argv)
window = QMainWindow()
window.setWindowTitle('3D Mesh Plot')
window.setGeometry(200, 200, 900, 700) # Set initial window size
# Create a central widget for displaying 3D graphics
central_widget = QWidget()
layout = QHBoxLayout()
central_widget.setLayout(layout)
window.setCentralWidget(central_widget)
# Create a widget for displaying 3D graphics
widget = gl.GLViewWidget()
widget.setCameraPosition(distance=300, azimuth=-90, elevation=90)
layout.addWidget(widget)
# Read vertices and faces from OBJ file
vertices, faces = read_obj_file('Female.obj')
# Triangulate the faces
faces = triangulate_faces(faces)
# Calculate the center of the mesh
center = vertices.mean(axis=0)
# Translate the mesh to center it at the origin
vertices -= center
# Create the mesh object
mesh = create_mesh(vertices, faces)
mesh.setGLOptions('translucent')
# Add the mesh to the widget
widget.addItem(mesh)
#calculate
plane = 0
test = plane_mesh_intersection(vertices, faces, plane)
# Add intersection points to the widget as spheres
for point in test:
sphere = gl.GLScatterPlotItem(pos=np.array([point]), color=(1, 0, 0, 1), size=10)
widget.addItem(sphere)
# Create a QWidget for displaying text boxes
text_widget = QWidget()
text_layout = QVBoxLayout()
text_widget.setLayout(text_layout)
layout.addWidget(text_widget)
layout.setStretch(0, 3) # Set stretch factor for the 3D graphics widget
layout.setStretch(1, 1) # Set stretch factor for the text widget
Labels = ["Height", "Weight", "Chest", "Waist", "Hips"]
Measurements = [0, 0, 0, 0, 0]
# Add multiple QLabel widgets with gray backgrounds
for i in range(5): # Change the range according to the number of text boxes you want
label = QLabel(Labels[i] + " : " + str(Measurements[i]))
label.setAlignment(Qt.AlignCenter) # Center the text horizontally and vertically
label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
label.setStyleSheet("background-color: lightgray; border: 1px solid gray; padding: 5px;")
text_layout.addWidget(label)
# Start the application event loop
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I hope this helps someone, but I was able to kind of fix this by modifying the shading of the mesh.
See the mesh and 3D points here!