184 lines
6.6 KiB
Python
184 lines
6.6 KiB
Python
from PySide6.QtOpenGLWidgets import QOpenGLWidget
|
|
from PySide6.QtCore import Qt, QPoint
|
|
from OpenGL.GL import *
|
|
from OpenGL.GLU import *
|
|
from stl import mesh
|
|
|
|
class OpenGLWidget(QOpenGLWidget):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.stl_file = "out.stl" # Replace with your STL file path
|
|
self.lastPos = QPoint()
|
|
self.startPos = None
|
|
self.endPos = None
|
|
self.xRot = 0
|
|
self.yRot = 0
|
|
self.zoom = -10.0
|
|
|
|
def map_value_to_range(self, value, value_min: int = 0, value_max: int= 1920, range_min=-1, range_max=1):
|
|
"""
|
|
Maps a value from one range to another.
|
|
|
|
Parameters:
|
|
value (float): The value to be mapped.
|
|
value_min (float): The minimum value of the input range.
|
|
value_max (float): The maximum value of the input range.
|
|
range_min (float, optional): The minimum value of the output range. Default is -1.
|
|
range_max (float, optional): The maximum value of the output range. Default is 1.
|
|
|
|
Returns:
|
|
float: The mapped value in the output range.
|
|
"""
|
|
# Ensure value is within the input range
|
|
value = max(value_min, min(value_max, value))
|
|
|
|
# Map the value to the output range
|
|
mapped_value = ((value - value_min) / (value_max - value_min)) * (range_max - range_min) + range_min
|
|
|
|
return mapped_value
|
|
|
|
def load_stl(self, filename):
|
|
try:
|
|
stl_mesh = mesh.Mesh.from_file(filename)
|
|
return stl_mesh.vectors
|
|
except FileNotFoundError:
|
|
print(f"Error: File {filename} not found.")
|
|
except Exception as e:
|
|
print(f"Error loading {filename}: {e}")
|
|
return []
|
|
|
|
def initializeGL(self):
|
|
glClearColor(0, 0, 0, 1)
|
|
glEnable(GL_DEPTH_TEST)
|
|
|
|
def resizeGL(self, width, height):
|
|
glViewport(0, 0, width, height)
|
|
glMatrixMode(GL_PROJECTION)
|
|
glLoadIdentity()
|
|
aspect = width / float(height)
|
|
|
|
gluPerspective(45.0, aspect, 1.0, 100.0)
|
|
glMatrixMode(GL_MODELVIEW)
|
|
|
|
def paintGL(self):
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
|
glLoadIdentity()
|
|
glTranslatef(0.0, 0.0, self.zoom)
|
|
glRotatef(self.xRot, 1.0, 0.0, 0.0)
|
|
glRotatef(self.yRot, 0.0, 1.0, 0.0)
|
|
glColor3f(1.0, 1.0, 1.0)
|
|
|
|
# Draw the rectangle if start and end positions are defined
|
|
self.draw_area()
|
|
if self.startPos and self.endPos:
|
|
self.draw_line(self.startPos, self.endPos)
|
|
|
|
|
|
def draw_area(self):
|
|
# Set line color
|
|
glColor3f(0.5, 0.5, 0.5) # Gray color
|
|
|
|
# Draw vertical lines
|
|
glBegin(GL_LINES)
|
|
for x in range(0, self.width(), 20):
|
|
x_ndc = self.map_value_to_range(x, 0, value_max=self.width(), range_min=-1, range_max=1)
|
|
glVertex2f(x_ndc, -1) # Start from y = -1
|
|
glVertex2f(x_ndc, 1) # End at y = 1
|
|
glEnd()
|
|
|
|
# Draw horizontal lines
|
|
glBegin(GL_LINES)
|
|
for y in range(0, self.height(), 20):
|
|
y_ndc = self.map_value_to_range(y, 0, value_max=self.height(),range_min=-1, range_max=1)
|
|
glVertex2f(-1, y_ndc) # Start from x = -1
|
|
glVertex2f(1, y_ndc) # End at x = 1
|
|
glEnd()
|
|
|
|
def draw_line(self, startPos, endPos):
|
|
# Get normalized mouse coordinates
|
|
print("start", startPos)
|
|
print("end", endPos)
|
|
x1, y1 = startPos
|
|
x2, y2 = endPos
|
|
|
|
# Adjust line width based on zoom level
|
|
line_width = abs(2.0 / self.zoom) # Adjust line width inversely proportional to zoom
|
|
glLineWidth(line_width)
|
|
|
|
# Adjust line color
|
|
glColor3f(1.0, 1.0, 0.0) # Yellow color
|
|
|
|
# Draw the line
|
|
glBegin(GL_LINES)
|
|
glVertex2f(x1, y1)
|
|
glVertex2f(x2, y2)
|
|
glEnd()
|
|
|
|
def mousePressEvent(self, event):
|
|
if event.buttons() & Qt.MouseButton.LeftButton:
|
|
# Get mouse position in widget coordinates
|
|
mouse_pos = event.pos()
|
|
|
|
# Map mouse position to normalized device coordinates
|
|
normalized_x = self.map_value_to_range(mouse_pos.x(), 0, self.width())
|
|
normalized_y = self.map_value_to_range(mouse_pos.y(), 0, self.height())
|
|
|
|
if event.buttons() & Qt.MouseButton.RightButton:
|
|
# Get mouse position in widget coordinates
|
|
mouse_pos = event.pos()
|
|
|
|
# Map mouse position to normalized device coordinates
|
|
normalized_x = self.map_value_to_range(mouse_pos.x(), 0, value_max=self.width(),range_min=-1, range_max=1)
|
|
normalized_y = self.map_value_to_range(mouse_pos.y(), 0, value_max=self.height(),range_min=-1, range_max=1)
|
|
|
|
self.startPos = [normalized_x, -normalized_y]
|
|
|
|
# Now you have the mouse position in normalized coordinates
|
|
print("Right mouse button pressed - Mouse position (normalized):", normalized_x, normalized_y)
|
|
|
|
"""def mouseReleaseEvent(self, event):
|
|
print("release")
|
|
|
|
# Get mouse position in widget coordinates
|
|
mouse_pos = event.pos()
|
|
|
|
# Map mouse position to normalized device coordinates
|
|
normalized_x = self.map_value_to_range(mouse_pos.x(), 0, self.width())
|
|
normalized_y = self.map_value_to_range(mouse_pos.y(), 0, self.height())
|
|
|
|
self.endPos = [normalized_x, normalized_y]
|
|
print(self.endPos)
|
|
|
|
# Now you have the mouse position in normalized coordinates
|
|
print("Right mouse button rel - Mouse position (normalized):", normalized_x, normalized_y)
|
|
#self.update()"""
|
|
|
|
def mouseMoveEvent(self, event):
|
|
dx = event.x() - self.lastPos.x()
|
|
dy = event.y() - self.lastPos.y()
|
|
|
|
if event.buttons() & Qt.MouseButton.LeftButton:
|
|
self.xRot += 0.5 * dy
|
|
self.yRot += 0.5 * dx
|
|
self.update()
|
|
self.lastPos = event.pos()
|
|
|
|
if event.buttons() & Qt.MouseButton.RightButton:
|
|
mouse_pos = event.pos()
|
|
|
|
# Map mouse position to normalized device coordinates
|
|
normalized_x = self.map_value_to_range(mouse_pos.x(), 0, self.width())
|
|
normalized_y = self.map_value_to_range(mouse_pos.y(), 0, self.height())
|
|
|
|
self.endPos = [normalized_x, -normalized_y]
|
|
print(self.endPos)
|
|
|
|
# Now you have the mouse position in normalized coordinates
|
|
print("Right mouse button rel - Mouse position (normalized):", normalized_x, normalized_y)
|
|
self.update()
|
|
def wheelEvent(self, event):
|
|
delta = event.angleDelta().y()
|
|
self.zoom += delta / 120
|
|
self.update()
|
|
|