From 8db6743dcd601d5919cb68a3c7967ed0a4c3c350 Mon Sep 17 00:00:00 2001
From: bklronin <therrmann23@gmail.com>
Date: Sat, 11 May 2024 20:27:03 +0200
Subject: [PATCH] 2d drawing test

---
 2d_draw.py           |  81 +++++++++++++++++++++
 main.py              |   1 +
 modules/gl_widget.py | 165 +++++++++++++++++++++++++++++++------------
 3 files changed, 202 insertions(+), 45 deletions(-)
 create mode 100644 2d_draw.py

diff --git a/2d_draw.py b/2d_draw.py
new file mode 100644
index 0000000..f2b6ffd
--- /dev/null
+++ b/2d_draw.py
@@ -0,0 +1,81 @@
+import sys
+
+from OpenGL.raw.GL.VERSION.GL_1_0 import glClearColor
+from PySide6.QtCore import Qt
+from PySide6.QtOpenGLWidgets import QOpenGLWidget
+from PySide6.QtWidgets import QDoubleSpinBox, QPushButton, QVBoxLayout, QApplication, QWidget
+from OpenGL.GL import *
+from OpenGL.GLUT import *
+
+class GLWidget(QOpenGLWidget):
+    def __init__(self, parent=None):
+        super(GLWidget, self).__init__(parent)
+        self.shapes = []
+        self.extruded_shapes = []
+
+    def initializeGL(self):
+        glClearColor(1, 1, 1, 1)
+
+    def paintGL(self):
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+        glLoadIdentity()
+        glColor3f(1, 0, 0)
+
+        for shape in self.shapes:
+            glBegin(GL_LINE_LOOP)
+            glVertex2f(shape[0], shape[1])  # Access x and y coordinates of the point
+            glEnd()
+
+    def resizeGL(self, w, h):
+        glViewport(0, 0, w, h)
+        glMatrixMode(GL_PROJECTION)
+        glLoadIdentity()
+        glOrtho(0, w, h, 0, -1, 1)
+        glMatrixMode(GL_MODELVIEW)
+
+    def mousePressEvent(self, event):
+        if event.button() == Qt.LeftButton:
+            pos = event.pos()
+            x = int(pos.x())
+            y = int(pos.y())
+            self.shapes.append((x, y))  # Append coordinate tuple (x, y)
+            self.update()
+    def extrude_shapes(self, height):
+        self.extruded_shapes = []
+        for shape in self.shapes:
+            extruded_shape = []
+            for point in shape:
+                extruded_shape.append([point[0], point[1]])
+            for point in shape:
+                extruded_shape.append([point[0], point[1] + height])
+            self.extruded_shapes.append(extruded_shape)
+
+class MainWindow(QWidget):
+    def __init__(self):
+        super(MainWindow, self).__init__()
+        self.gl_widget = GLWidget()
+        self.height_spin_box = QDoubleSpinBox()
+        self.height_spin_box.setRange(0, 100)
+        self.height_spin_box.setValue(10)
+        self.extrude_button = QPushButton("Extrude")
+        self.extrude_button.clicked.connect(self.extrude_shapes)
+
+        layout = QVBoxLayout()
+        layout.addWidget(self.gl_widget)
+        layout.addWidget(self.height_spin_box)
+        layout.addWidget(self.extrude_button)
+
+        self.setLayout(layout)
+
+    def extrude_shapes(self):
+        height = self.height_spin_box.value()
+        self.gl_widget.extrude_shapes(height)
+        self.gl_widget.update()
+
+if __name__ == "__main__":
+    app = QApplication(sys.argv)
+    window = MainWindow()
+    window.setGeometry(100, 100, 800, 600)
+    window.setWindowTitle("Extrude Shapes")
+    window.show()
+    sys.exit(app.exec_())
\ No newline at end of file
diff --git a/main.py b/main.py
index 1688d58..78d7fe3 100644
--- a/main.py
+++ b/main.py
@@ -19,6 +19,7 @@ class MainWindow(QMainWindow):
 
         self.ui.pb_apply_code.pressed.connect(self.generate_mesh)
 
+
     def generate_mesh(self):
         code_bytes = self.ui.textEdit.toPlainText().encode('utf-8')
         code_text = code_bytes.decode('utf-8')
diff --git a/modules/gl_widget.py b/modules/gl_widget.py
index af01371..86179ab 100644
--- a/modules/gl_widget.py
+++ b/modules/gl_widget.py
@@ -1,19 +1,42 @@
 from PySide6.QtOpenGLWidgets import QOpenGLWidget
-from PySide6.QtCore import QSize, Qt, QPoint
+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)
@@ -28,11 +51,13 @@ class OpenGLWidget(QOpenGLWidget):
         glClearColor(0, 0, 0, 1)
         glEnable(GL_DEPTH_TEST)
 
-    def resizeGL(self, w, h):
-        glViewport(0, 0, w, h)
+    def resizeGL(self, width, height):
+        glViewport(0, 0, width, height)
         glMatrixMode(GL_PROJECTION)
         glLoadIdentity()
-        gluPerspective(45, w/h, 0.1, 100.0)
+        aspect = width / float(height)
+
+        gluPerspective(45.0, aspect, 1.0, 100.0)
         glMatrixMode(GL_MODELVIEW)
 
     def paintGL(self):
@@ -43,66 +68,116 @@ class OpenGLWidget(QOpenGLWidget):
         glRotatef(self.yRot, 0.0, 1.0, 0.0)
         glColor3f(1.0, 1.0, 1.0)
 
-        mesh_data = self.load_stl(self.stl_file)
-        if mesh_data.any():
-            self.draw_stl(mesh_data)
+        # 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_stl(self, vertices):
-        glEnable(GL_LIGHTING)
-        glEnable(GL_LIGHT0)
-        glEnable(GL_DEPTH_TEST)
-        glEnable(GL_COLOR_MATERIAL)
-        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
 
-        glLightfv(GL_LIGHT0, GL_POSITION, (0, 1, 1, 0))
-        glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.6, 0.6, 0.6, 0.6))
+    def draw_area(self):
+        # Set line color
+        glColor3f(0.5, 0.5, 0.5)  # Gray color
 
-        glBegin(GL_TRIANGLES)
-        for triangle in vertices:
-            for vertex in triangle:
-                glVertex3fv(vertex)
-        glEnd()
-
-        # Draw outer vertices as points
-        glDisable(GL_LIGHTING)
-        glColor3f(1.0, 0.0, 0.0)  # Set color to red
-        glPointSize(5.0)  # Set point size
-        glBegin(GL_POINTS)
-        for triangle in vertices:
-            for vertex in triangle:
-                glVertex3fv(vertex)
-        glEnd()
-
-        # Draw edges
-        glColor3f(0.0, 0.0, 1.0)  # Set color to blue
-        glLineWidth(2.0)  # Set line width
+        # Draw vertical lines
         glBegin(GL_LINES)
-        for triangle in vertices:
-            glVertex3fv(triangle[0])
-            glVertex3fv(triangle[1])
+        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()
 
-            glVertex3fv(triangle[1])
-            glVertex3fv(triangle[2])
+        # 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()
 
-            glVertex3fv(triangle[2])
-            glVertex3fv(triangle[0])
+    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):
-        self.lastPos = event.pos()
+        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.LeftButton:
+        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()
+