- Extrude and cut
This commit is contained in:
parent
e35ff3e9a1
commit
055a90b62e
166
Gui.py
166
Gui.py
@ -16,15 +16,15 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QGroupBox, QHBoxLayout,
|
||||
QHeaderView, QMainWindow, QMenuBar, QPushButton,
|
||||
QSizePolicy, QStatusBar, QTabWidget, QTextEdit,
|
||||
QTreeView, QVBoxLayout, QWidget)
|
||||
QListWidget, QListWidgetItem, QMainWindow, QMenuBar,
|
||||
QPushButton, QSizePolicy, QStatusBar, QTabWidget,
|
||||
QTextEdit, QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_fluencyCAD(object):
|
||||
def setupUi(self, fluencyCAD):
|
||||
if not fluencyCAD.objectName():
|
||||
fluencyCAD.setObjectName(u"fluencyCAD")
|
||||
fluencyCAD.resize(1755, 671)
|
||||
fluencyCAD.resize(1755, 685)
|
||||
self.centralwidget = QWidget(fluencyCAD)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.gridLayout = QGridLayout(self.centralwidget)
|
||||
@ -60,25 +60,25 @@ class Ui_fluencyCAD(object):
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.gridLayout_3 = QGridLayout(self.groupBox)
|
||||
self.gridLayout_3.setObjectName(u"gridLayout_3")
|
||||
self.pushButton_7 = QPushButton(self.groupBox)
|
||||
self.pushButton_7.setObjectName(u"pushButton_7")
|
||||
self.pb_extrdop = QPushButton(self.groupBox)
|
||||
self.pb_extrdop.setObjectName(u"pb_extrdop")
|
||||
|
||||
self.gridLayout_3.addWidget(self.pushButton_7, 0, 0, 1, 1)
|
||||
self.gridLayout_3.addWidget(self.pb_extrdop, 0, 0, 1, 1)
|
||||
|
||||
self.pushButton_14 = QPushButton(self.groupBox)
|
||||
self.pushButton_14.setObjectName(u"pushButton_14")
|
||||
self.pb_cutop = QPushButton(self.groupBox)
|
||||
self.pb_cutop.setObjectName(u"pb_cutop")
|
||||
|
||||
self.gridLayout_3.addWidget(self.pushButton_14, 0, 1, 1, 1)
|
||||
self.gridLayout_3.addWidget(self.pb_cutop, 0, 1, 1, 1)
|
||||
|
||||
self.pushButton_15 = QPushButton(self.groupBox)
|
||||
self.pushButton_15.setObjectName(u"pushButton_15")
|
||||
self.pb_arrayop = QPushButton(self.groupBox)
|
||||
self.pb_arrayop.setObjectName(u"pb_arrayop")
|
||||
|
||||
self.gridLayout_3.addWidget(self.pushButton_15, 1, 1, 1, 1)
|
||||
self.gridLayout_3.addWidget(self.pb_arrayop, 1, 0, 1, 1)
|
||||
|
||||
self.pushButton_16 = QPushButton(self.groupBox)
|
||||
self.pushButton_16.setObjectName(u"pushButton_16")
|
||||
self.pb_revop = QPushButton(self.groupBox)
|
||||
self.pb_revop.setObjectName(u"pb_revop")
|
||||
|
||||
self.gridLayout_3.addWidget(self.pushButton_16, 1, 0, 1, 1)
|
||||
self.gridLayout_3.addWidget(self.pb_revop, 1, 1, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox, 0, 5, 3, 1, Qt.AlignTop)
|
||||
@ -92,16 +92,16 @@ class Ui_fluencyCAD(object):
|
||||
|
||||
self.verticalLayout_2.addWidget(self.pb_nw_sktch)
|
||||
|
||||
self.pb_edt_sktch = QPushButton(self.groupBox_6)
|
||||
self.pb_edt_sktch.setObjectName(u"pb_edt_sktch")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.pb_edt_sktch)
|
||||
|
||||
self.pb_del_sketch = QPushButton(self.groupBox_6)
|
||||
self.pb_del_sketch.setObjectName(u"pb_del_sketch")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.pb_del_sketch)
|
||||
|
||||
self.pb_edt_sktch = QPushButton(self.groupBox_6)
|
||||
self.pb_edt_sktch.setObjectName(u"pb_edt_sktch")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.pb_edt_sktch)
|
||||
|
||||
self.pushButton_13 = QPushButton(self.groupBox_6)
|
||||
self.pushButton_13.setObjectName(u"pushButton_13")
|
||||
|
||||
@ -110,33 +110,6 @@ class Ui_fluencyCAD(object):
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_6, 0, 0, 1, 1)
|
||||
|
||||
self.groupBox_3 = QGroupBox(self.centralwidget)
|
||||
self.groupBox_3.setObjectName(u"groupBox_3")
|
||||
self.gridLayout_4 = QGridLayout(self.groupBox_3)
|
||||
self.gridLayout_4.setObjectName(u"gridLayout_4")
|
||||
self.pb_con_line = QPushButton(self.groupBox_3)
|
||||
self.pb_con_line.setObjectName(u"pb_con_line")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_line, 0, 1, 1, 1)
|
||||
|
||||
self.pb_con_ptpt = QPushButton(self.groupBox_3)
|
||||
self.pb_con_ptpt.setObjectName(u"pb_con_ptpt")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_ptpt, 0, 0, 1, 1)
|
||||
|
||||
self.pb_con_horiz = QPushButton(self.groupBox_3)
|
||||
self.pb_con_horiz.setObjectName(u"pb_con_horiz")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_horiz, 1, 0, 1, 1)
|
||||
|
||||
self.pb_con_vert = QPushButton(self.groupBox_3)
|
||||
self.pb_con_vert.setObjectName(u"pb_con_vert")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_vert, 1, 1, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1)
|
||||
|
||||
self.groupBox_7 = QGroupBox(self.centralwidget)
|
||||
self.groupBox_7.setObjectName(u"groupBox_7")
|
||||
self.verticalLayout_5 = QVBoxLayout(self.groupBox_7)
|
||||
@ -169,13 +142,58 @@ class Ui_fluencyCAD(object):
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_7, 3, 0, 1, 1)
|
||||
|
||||
self.InputTab = QTabWidget(self.centralwidget)
|
||||
self.InputTab.setObjectName(u"InputTab")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
self.groupBox_3 = QGroupBox(self.centralwidget)
|
||||
self.groupBox_3.setObjectName(u"groupBox_3")
|
||||
self.gridLayout_4 = QGridLayout(self.groupBox_3)
|
||||
self.gridLayout_4.setObjectName(u"gridLayout_4")
|
||||
self.pb_con_line = QPushButton(self.groupBox_3)
|
||||
self.pb_con_line.setObjectName(u"pb_con_line")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_line, 0, 1, 1, 1)
|
||||
|
||||
self.pb_con_ptpt = QPushButton(self.groupBox_3)
|
||||
self.pb_con_ptpt.setObjectName(u"pb_con_ptpt")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_ptpt, 0, 0, 1, 1)
|
||||
|
||||
self.pb_con_horiz = QPushButton(self.groupBox_3)
|
||||
self.pb_con_horiz.setObjectName(u"pb_con_horiz")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_horiz, 1, 0, 1, 1)
|
||||
|
||||
self.pb_con_vert = QPushButton(self.groupBox_3)
|
||||
self.pb_con_vert.setObjectName(u"pb_con_vert")
|
||||
|
||||
self.gridLayout_4.addWidget(self.pb_con_vert, 1, 1, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1)
|
||||
|
||||
self.groupBox_5 = QGroupBox(self.centralwidget)
|
||||
self.groupBox_5.setObjectName(u"groupBox_5")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.InputTab.sizePolicy().hasHeightForWidth())
|
||||
self.InputTab.setSizePolicy(sizePolicy)
|
||||
sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_5.setSizePolicy(sizePolicy)
|
||||
self.groupBox_5.setMaximumSize(QSize(300, 16777215))
|
||||
self.verticalLayout_3 = QVBoxLayout(self.groupBox_5)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.element_list = QListWidget(self.groupBox_5)
|
||||
self.element_list.setObjectName(u"element_list")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.element_list)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_5, 0, 3, 4, 1)
|
||||
|
||||
self.InputTab = QTabWidget(self.centralwidget)
|
||||
self.InputTab.setObjectName(u"InputTab")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.InputTab.sizePolicy().hasHeightForWidth())
|
||||
self.InputTab.setSizePolicy(sizePolicy1)
|
||||
self.sketch_tab = QWidget()
|
||||
self.sketch_tab.setObjectName(u"sketch_tab")
|
||||
self.verticalLayout_4 = QVBoxLayout(self.sketch_tab)
|
||||
@ -194,24 +212,6 @@ class Ui_fluencyCAD(object):
|
||||
|
||||
self.gridLayout.addWidget(self.InputTab, 0, 2, 4, 1)
|
||||
|
||||
self.groupBox_5 = QGroupBox(self.centralwidget)
|
||||
self.groupBox_5.setObjectName(u"groupBox_5")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox_5.setSizePolicy(sizePolicy1)
|
||||
self.groupBox_5.setMaximumSize(QSize(300, 16777215))
|
||||
self.verticalLayout_3 = QVBoxLayout(self.groupBox_5)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.comp_tree = QTreeView(self.groupBox_5)
|
||||
self.comp_tree.setObjectName(u"comp_tree")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.comp_tree)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.groupBox_5, 0, 3, 4, 1)
|
||||
|
||||
self.gl_box = QGroupBox(self.centralwidget)
|
||||
self.gl_box.setObjectName(u"gl_box")
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
|
||||
@ -256,29 +256,29 @@ class Ui_fluencyCAD(object):
|
||||
self.pb_circtool.setText(QCoreApplication.translate("fluencyCAD", u"Circle", None))
|
||||
self.pb_slotool.setText(QCoreApplication.translate("fluencyCAD", u"Slot", None))
|
||||
self.groupBox.setTitle(QCoreApplication.translate("fluencyCAD", u"Modify", None))
|
||||
self.pushButton_7.setText(QCoreApplication.translate("fluencyCAD", u"Cut", None))
|
||||
self.pushButton_14.setText(QCoreApplication.translate("fluencyCAD", u"Arry", None))
|
||||
self.pushButton_15.setText(QCoreApplication.translate("fluencyCAD", u"Extrd", None))
|
||||
self.pushButton_16.setText(QCoreApplication.translate("fluencyCAD", u"Rev", None))
|
||||
self.pb_extrdop.setText(QCoreApplication.translate("fluencyCAD", u"Extrd", None))
|
||||
self.pb_cutop.setText(QCoreApplication.translate("fluencyCAD", u"Cut", None))
|
||||
self.pb_arrayop.setText(QCoreApplication.translate("fluencyCAD", u"Arry", None))
|
||||
self.pb_revop.setText(QCoreApplication.translate("fluencyCAD", u"Rev", None))
|
||||
self.groupBox_6.setTitle(QCoreApplication.translate("fluencyCAD", u"Sketchtools", None))
|
||||
self.pb_nw_sktch.setText(QCoreApplication.translate("fluencyCAD", u"Nw Sktch Wp", None))
|
||||
self.pb_edt_sktch.setText(QCoreApplication.translate("fluencyCAD", u"Edt Sketch", None))
|
||||
self.pb_nw_sktch.setText(QCoreApplication.translate("fluencyCAD", u"Add Sketch", None))
|
||||
self.pb_del_sketch.setText(QCoreApplication.translate("fluencyCAD", u"Sktch del", None))
|
||||
self.pb_edt_sktch.setText(QCoreApplication.translate("fluencyCAD", u"Edt Sketch", None))
|
||||
self.pushButton_13.setText(QCoreApplication.translate("fluencyCAD", u"PushButton", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("fluencyCAD", u"Constrain", None))
|
||||
self.pb_con_line.setText(QCoreApplication.translate("fluencyCAD", u"Pt_Line", None))
|
||||
self.pb_con_ptpt.setText(QCoreApplication.translate("fluencyCAD", u"Pt_Pt", None))
|
||||
self.pb_con_horiz.setText(QCoreApplication.translate("fluencyCAD", u"Horiz", None))
|
||||
self.pb_con_vert.setText(QCoreApplication.translate("fluencyCAD", u"Vert", None))
|
||||
self.groupBox_7.setTitle(QCoreApplication.translate("fluencyCAD", u"Executive", None))
|
||||
self.pb_apply_code.setText(QCoreApplication.translate("fluencyCAD", u"Apply Code", None))
|
||||
self.pushButton.setText(QCoreApplication.translate("fluencyCAD", u"Delete Code", None))
|
||||
self.pushButton_5.setText(QCoreApplication.translate("fluencyCAD", u"Load Code", None))
|
||||
self.pushButton_4.setText(QCoreApplication.translate("fluencyCAD", u"Save code", None))
|
||||
self.pushButton_2.setText(QCoreApplication.translate("fluencyCAD", u"Export STL", None))
|
||||
self.groupBox_3.setTitle(QCoreApplication.translate("fluencyCAD", u"Constrain", None))
|
||||
self.pb_con_line.setText(QCoreApplication.translate("fluencyCAD", u"Pt_Line", None))
|
||||
self.pb_con_ptpt.setText(QCoreApplication.translate("fluencyCAD", u"Pt_Pt", None))
|
||||
self.pb_con_horiz.setText(QCoreApplication.translate("fluencyCAD", u"Horiz", None))
|
||||
self.pb_con_vert.setText(QCoreApplication.translate("fluencyCAD", u"Vert", None))
|
||||
self.groupBox_5.setTitle(QCoreApplication.translate("fluencyCAD", u"Components", None))
|
||||
self.InputTab.setTabText(self.InputTab.indexOf(self.sketch_tab), QCoreApplication.translate("fluencyCAD", u"Sketch", None))
|
||||
self.InputTab.setTabText(self.InputTab.indexOf(self.code_tab), QCoreApplication.translate("fluencyCAD", u"Code", None))
|
||||
self.groupBox_5.setTitle(QCoreApplication.translate("fluencyCAD", u"Components", None))
|
||||
self.gl_box.setTitle(QCoreApplication.translate("fluencyCAD", u"Model Viewer", None))
|
||||
# retranslateUi
|
||||
|
||||
|
@ -10,12 +10,13 @@ class SnapLineWidget(QWidget):
|
||||
self.selected_line = None
|
||||
self.snapping_range = 20 # Range in pixels for snapping
|
||||
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if event.button() == Qt.LeftButton:
|
||||
if event.button() == Qt.LeftButton :
|
||||
self.points.append(event.pos())
|
||||
self.update()
|
||||
|
||||
if event.button() == Qt.RightButton:
|
||||
elif event.button() == Qt.RightButton:
|
||||
for i in range(len(self.points) - 1):
|
||||
if self.is_point_on_line(event.pos(), self.points[i], self.points[i + 1]):
|
||||
self.selected_line = i
|
||||
@ -24,7 +25,7 @@ class SnapLineWidget(QWidget):
|
||||
self.selected_line = None
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
if event.buttons() & Qt.LeftButton:
|
||||
if event.buttons() & Qt.RightButton:
|
||||
if self.selected_line is not None:
|
||||
self.points[self.selected_line] = event.pos()
|
||||
else:
|
||||
@ -41,7 +42,8 @@ class SnapLineWidget(QWidget):
|
||||
distance1 = self.distance(p, p1)
|
||||
distance2 = self.distance(p, p2)
|
||||
total_distance = self.distance(p1, p2)
|
||||
return abs(distance1 + distance2 - total_distance) < 0.1
|
||||
|
||||
return abs(distance1 + distance2 - total_distance) < 1
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QPainter(self)
|
||||
@ -65,6 +67,11 @@ class SnapLineWidget(QWidget):
|
||||
p2 = self.points[self.selected_line + 1]
|
||||
painter.setPen(QPen(Qt.red, 2))
|
||||
painter.drawLine(p1, p2)
|
||||
painter.end()
|
||||
|
||||
def clear_sketch(self):
|
||||
self.points = []
|
||||
self.update()
|
||||
|
||||
|
||||
# Example usage
|
||||
|
@ -8,13 +8,16 @@ from stl import mesh
|
||||
class OpenGLWidget(QOpenGLWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.scale_factor = 0.001
|
||||
self.mesh_loaded = None
|
||||
self.centroid = None
|
||||
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
|
||||
self.zoom = -2
|
||||
self.sketch = []
|
||||
self.gl_width = self.width() / 1000
|
||||
self.gl_height = self.height() / 1000
|
||||
@ -22,9 +25,11 @@ class OpenGLWidget(QOpenGLWidget):
|
||||
def map_value_to_range(self, value, value_min=0, value_max=1920, range_min=-1, range_max=1):
|
||||
value = max(value_min, min(value_max, value))
|
||||
mapped_value = ((value - value_min) / (value_max - value_min)) * (range_max - range_min) + range_min
|
||||
|
||||
return mapped_value
|
||||
|
||||
def load_stl(self, filename):
|
||||
|
||||
def load_stl(self, filename: str) -> object:
|
||||
try:
|
||||
stl_mesh = mesh.Mesh.from_file(filename)
|
||||
|
||||
@ -40,17 +45,37 @@ class OpenGLWidget(QOpenGLWidget):
|
||||
centroid_y = (min_y + max_y) / 2.0
|
||||
centroid_z = (min_z + max_z) / 2.0
|
||||
|
||||
return stl_mesh.vectors, (centroid_x, centroid_y, centroid_z)
|
||||
self.mesh_loaded = stl_mesh.vectors
|
||||
self.centroid = (centroid_x, centroid_y, centroid_z)
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File {filename} not found.")
|
||||
except Exception as e:
|
||||
print(f"Error loading {filename}: {e}")
|
||||
|
||||
return None, (0, 0, 0)
|
||||
|
||||
def load_mesh_direct(self, mesh) -> object:
|
||||
try:
|
||||
stl_mesh = mesh
|
||||
|
||||
# Extract vertices
|
||||
vertices = np.array(stl_mesh)
|
||||
|
||||
# Calculate centroid based on the average position of vertices
|
||||
centroid = np.mean(vertices, axis=0)
|
||||
|
||||
self.mesh_loaded = vertices
|
||||
self.centroid = tuple(centroid)
|
||||
print(f"Centroid: {self.centroid}")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
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)
|
||||
@ -60,36 +85,33 @@ class OpenGLWidget(QOpenGLWidget):
|
||||
self.gl_width = self.width() / 1000
|
||||
self.gl_height = self.height() / 1000
|
||||
|
||||
gluPerspective(45.0, aspect, 1.0, 1000.0)
|
||||
gluPerspective(45.0, aspect, 1.0, 10000.0)
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
|
||||
|
||||
def paintGL(self):
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
glLoadIdentity()
|
||||
|
||||
mesh_loaded, centroid = self.load_stl(self.stl_file)
|
||||
centroid_x, centroid_y, centroid_z = centroid
|
||||
|
||||
glTranslatef(0, 0, self.zoom)
|
||||
glRotatef(self.xRot, 1.0, 0.0, 0.0)
|
||||
glRotatef(self.yRot, 0.0, 1.0, 0.0)
|
||||
glRotatef(self.xRot, 0.0, 0.0, 0.0)
|
||||
glRotatef(self.yRot, 0.0, 0.0, 0.0)
|
||||
|
||||
glColor3f(1.0, 1.0, 1.0)
|
||||
|
||||
self.draw_area()
|
||||
|
||||
if mesh is not None:
|
||||
# Scale the object
|
||||
scale_factor = 0.001 # Example scale factor (adjust as needed)
|
||||
glScalef(scale_factor, scale_factor, scale_factor)
|
||||
if self.mesh_loaded is not None:
|
||||
# Adjust the camera
|
||||
if self.centroid:
|
||||
glScalef(self.scale_factor, self.scale_factor, self.scale_factor) # Apply scaling
|
||||
|
||||
# Translate to move the centroid of the object to the origin
|
||||
glTranslatef(-centroid_x, -centroid_y, -centroid_z)
|
||||
cx, cy, cz = self.centroid
|
||||
gluLookAt(cx, cy, cz + 100, cx, cy, cz, 0, 1, 0)
|
||||
|
||||
self.draw_mesh_direct(self.mesh_loaded)
|
||||
|
||||
|
||||
self.draw_stl(mesh_loaded)
|
||||
|
||||
def draw_stl(self, vertices):
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
@ -105,15 +127,24 @@ class OpenGLWidget(QOpenGLWidget):
|
||||
for vertex in triangle:
|
||||
glVertex3fv(vertex)
|
||||
glEnd()
|
||||
self.update()
|
||||
|
||||
"""# 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 vertex in vertices:
|
||||
def draw_mesh_direct(self, points):
|
||||
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, 1.0))
|
||||
|
||||
glBegin(GL_TRIANGLES)
|
||||
for vertex in points:
|
||||
glVertex3fv(vertex)
|
||||
glEnd()"""
|
||||
glEnd()
|
||||
self.update()
|
||||
|
||||
|
||||
def draw_area(self):
|
||||
glColor3f(0.5, 0.5, 0.5) # Gray color
|
||||
|
162
gui.ui
162
gui.ui
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1755</width>
|
||||
<height>671</height>
|
||||
<height>685</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -59,28 +59,28 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pushButton_7">
|
||||
<widget class="QPushButton" name="pb_extrdop">
|
||||
<property name="text">
|
||||
<string>Extrd</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pb_cutop">
|
||||
<property name="text">
|
||||
<string>Cut</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pushButton_14">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pb_arrayop">
|
||||
<property name="text">
|
||||
<string>Arry</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pushButton_15">
|
||||
<property name="text">
|
||||
<string>Extrd</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pushButton_16">
|
||||
<widget class="QPushButton" name="pb_revop">
|
||||
<property name="text">
|
||||
<string>Rev</string>
|
||||
</property>
|
||||
@ -98,14 +98,7 @@
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_nw_sktch">
|
||||
<property name="text">
|
||||
<string>Nw Sktch Wp</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_edt_sktch">
|
||||
<property name="text">
|
||||
<string>Edt Sketch</string>
|
||||
<string>Add Sketch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -116,6 +109,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pb_edt_sktch">
|
||||
<property name="text">
|
||||
<string>Edt Sketch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_13">
|
||||
<property name="text">
|
||||
@ -126,43 +126,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Constrain</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pb_con_line">
|
||||
<property name="text">
|
||||
<string>Pt_Line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pb_con_ptpt">
|
||||
<property name="text">
|
||||
<string>Pt_Pt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pb_con_horiz">
|
||||
<property name="text">
|
||||
<string>Horiz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pb_con_vert">
|
||||
<property name="text">
|
||||
<string>Vert</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_7">
|
||||
<property name="title">
|
||||
@ -207,6 +170,67 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Constrain</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="pb_con_line">
|
||||
<property name="text">
|
||||
<string>Pt_Line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pb_con_ptpt">
|
||||
<property name="text">
|
||||
<string>Pt_Pt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pb_con_horiz">
|
||||
<property name="text">
|
||||
<string>Horiz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pb_con_vert">
|
||||
<property name="text">
|
||||
<string>Vert</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="4">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Components</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QListWidget" name="element_list"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="4">
|
||||
<widget class="QTabWidget" name="InputTab">
|
||||
<property name="sizePolicy">
|
||||
@ -236,30 +260,6 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="4">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Components</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTreeView" name="comp_tree"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="4">
|
||||
<widget class="QGroupBox" name="gl_box">
|
||||
<property name="sizePolicy">
|
||||
|
195
main.py
195
main.py
@ -1,3 +1,5 @@
|
||||
import uuid
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QApplication, QMainWindow, QSizePolicy
|
||||
from Gui import Ui_fluencyCAD # Import the generated GUI module
|
||||
from drawing_modules.gl_widget import OpenGLWidget
|
||||
@ -5,11 +7,17 @@ from drawing_modules.draw_widget2d import SnapLineWidget
|
||||
from sdf import *
|
||||
import python_solvespace
|
||||
|
||||
|
||||
|
||||
# main, draw_widget, gl_widget
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Set up the UI from the generated GUI module
|
||||
|
||||
|
||||
self.ui = Ui_fluencyCAD()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
@ -24,21 +32,133 @@ class MainWindow(QMainWindow):
|
||||
layout2.addWidget(self.sketchWidget)
|
||||
size_policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
|
||||
self.sketchWidget.setSizePolicy(size_policy)
|
||||
self.sketchWidget.setStyleSheet("background-color: white; border: 1px solid red;")
|
||||
|
||||
self.ui.pb_apply_code.pressed.connect(self.check_current_tab)
|
||||
### Main Model
|
||||
self.model = {
|
||||
'sketch': {},
|
||||
'operations': {},
|
||||
}
|
||||
self.list_selected = []
|
||||
|
||||
def check_current_tab(self):
|
||||
if self.ui.InputTab.currentIndex() == 0:
|
||||
self.generate_mesh_from_draw()
|
||||
elif self.ui.InputTab.currentIndex() == 1:
|
||||
self.generate_mesh_from_code()
|
||||
#self.ui.pb_apply_code.pressed.connect(self.check_current_tab)
|
||||
self.ui.element_list.currentItemChanged.connect(self.on_item_changed)
|
||||
self.ui.element_list.itemChanged.connect(self.view_update)
|
||||
|
||||
def load_and_render(self, file, centroid):
|
||||
self.openGLWidget.draw_stl(file)
|
||||
### Sketches
|
||||
self.ui.pb_nw_sktch.pressed.connect(self.add_sketch)
|
||||
self.ui.pb_del_sketch.pressed.connect(self.reset_pos_list)
|
||||
|
||||
### Operations
|
||||
self.ui.pb_extrdop.pressed.connect(self.send_extrude)
|
||||
self.ui.pb_cutop.pressed.connect(self.send_cut)
|
||||
|
||||
def view_update(self):
|
||||
print("Update")
|
||||
name = self.ui.element_list.currentItem().text()
|
||||
print("selcted_for disp", name)
|
||||
model = self.model['operations'][name]['sdf_object']
|
||||
mesh = model.generate(samples=2**12)
|
||||
self.openGLWidget.load_mesh_direct(mesh)
|
||||
|
||||
def on_item_changed(self, current_item, previous_item):
|
||||
if current_item:
|
||||
name = current_item.text()
|
||||
#self.view_update()
|
||||
print(f"Selected item: {name}")
|
||||
|
||||
def add_sketch(self):
|
||||
p_list = []
|
||||
name = f"sketch-{str(uuid.uuid4())}"
|
||||
points = self.sketchWidget.points
|
||||
|
||||
for ps in points:
|
||||
p_list.append((ps.x(), ps.y()))
|
||||
|
||||
element = {
|
||||
'id': name,
|
||||
'type': 'polygon',
|
||||
'sketch_points': p_list,
|
||||
}
|
||||
|
||||
self.model['sketch'][element['id']] = element
|
||||
print(self.model)
|
||||
|
||||
self.ui.element_list.addItem(name)
|
||||
|
||||
def send_extrude(self):
|
||||
selected = self.ui.element_list.currentItem()
|
||||
name = selected.text()
|
||||
points = self.model['sketch'][name]['sketch_points']
|
||||
|
||||
geo = Geometry()
|
||||
f = geo.extrude_shape(points)
|
||||
|
||||
element = {
|
||||
'id': name,
|
||||
'type': 'extrude',
|
||||
'sdf_object': f,
|
||||
}
|
||||
|
||||
name_op = f"extrd-{name}"
|
||||
self.model['operations'][name_op] = element
|
||||
self.ui.element_list.addItem(name_op)
|
||||
items = self.ui.element_list.findItems(name_op, Qt.MatchExactly)
|
||||
self.ui.element_list.setCurrentItem(items[0])
|
||||
self.view_update()
|
||||
|
||||
def send_cut(self):
|
||||
name = self.ui.element_list.currentItem().text()
|
||||
points = self.model['operations'][name]['sdf_object']
|
||||
self.list_selected.append(points)
|
||||
print(self.list_selected)
|
||||
|
||||
if len(self.list_selected) > 1:
|
||||
geo = Geometry()
|
||||
f = geo.cut_shapes(self.list_selected[0], self.list_selected[1] )
|
||||
|
||||
element = {
|
||||
'id': name,
|
||||
'type': 'cut',
|
||||
'sdf_object': f,
|
||||
}
|
||||
|
||||
name_op = f"cut-{name}"
|
||||
self.model['operations'][name_op] = element
|
||||
self.ui.element_list.addItem(name_op)
|
||||
items = self.ui.element_list.findItems(name_op, Qt.MatchExactly)
|
||||
self.ui.element_list.setCurrentItem(items[0])
|
||||
self.view_update()
|
||||
|
||||
else:
|
||||
print("mindestens 2!")
|
||||
|
||||
def load_and_render(self, file):
|
||||
self.openGLWidget.load_stl(file)
|
||||
self.openGLWidget.update()
|
||||
|
||||
|
||||
def reset_pos_list(self):
|
||||
print("Deleting")
|
||||
self.sketchWidget.clear_sketch()
|
||||
|
||||
|
||||
""" def check_current_tab(self):
|
||||
if self.ui.InputTab.currentIndex() == 0:
|
||||
geo = Geometry()
|
||||
geo.generate_mesh_from_draw(self.sketchWidget.points)
|
||||
self.load_and_render("out.stl")
|
||||
|
||||
elif self.ui.InputTab.currentIndex() == 1:
|
||||
code_bytes = self.ui.textEdit.toPlainText().encode('utf-8')
|
||||
code_text = code_bytes.decode('utf-8')
|
||||
save_string = "\nf.save('out.stl', samples=2**12)"
|
||||
code_text += save_string
|
||||
|
||||
geo = Geometry()
|
||||
geo.generate_mesh_from_code(code_text)
|
||||
self.load_and_render("out.stl")"""
|
||||
|
||||
|
||||
|
||||
class Geometry:
|
||||
def distance(self, p1, p2):
|
||||
@ -47,13 +167,25 @@ class Geometry:
|
||||
print("p2", p2)
|
||||
return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
|
||||
|
||||
def generate_mesh_from_code(self):
|
||||
code_bytes = self.ui.textEdit.toPlainText().encode('utf-8')
|
||||
code_text = code_bytes.decode('utf-8')
|
||||
save_string = "\nf.save('out.stl', samples=2**12)"
|
||||
code_text += save_string
|
||||
def extrude_shape(self, points):
|
||||
"""2D to 3D sdf always first"""
|
||||
f = polygon(points).extrude(100)
|
||||
|
||||
return f
|
||||
|
||||
def cut_shapes(self, sdf_object1, sdf_object2):
|
||||
f = difference(sdf_object1, sdf_object2) # equivalent
|
||||
|
||||
return f
|
||||
|
||||
def export_mesh(self, sdf_object):
|
||||
"""FINAL EXPORT"""
|
||||
result_points = sdf_object.generate()
|
||||
write_binary_stl('out.stl', result_points)
|
||||
|
||||
def generate_mesh_from_code(self, code_text: str):
|
||||
local_vars = {}
|
||||
|
||||
try:
|
||||
print(code_text)
|
||||
exec(code_text, globals(), local_vars)
|
||||
@ -61,43 +193,10 @@ class Geometry:
|
||||
# Retrieve the result from the captured local variables
|
||||
result = local_vars.get('result')
|
||||
print("Result:", result)
|
||||
mesh = self.openGLWidget.load_stl("out.stl")
|
||||
self.openGLWidget.draw_stl(mesh)
|
||||
|
||||
except Exception as e:
|
||||
print("Error executing code:", e)
|
||||
|
||||
def generate_mesh_from_draw(self, points, ):
|
||||
f = None
|
||||
points = MainWindow().sketchWidget.points
|
||||
print(points)
|
||||
p_list = []
|
||||
dimension = 0.001
|
||||
for ps in points:
|
||||
p_list.append((ps.x() , ps.y()))
|
||||
|
||||
#p_list.append(p_list[0])
|
||||
print(p_list)
|
||||
f = polygon(p_list).extrude(100)
|
||||
|
||||
"""if len(points) > 3:
|
||||
p1 = [points[0].x(), points[0].y()]
|
||||
p2 = [points[1].x(), points[1].y()]
|
||||
dimension = self.distance(p1, p2)
|
||||
scale = 0.001
|
||||
f = box(dimension * scale)
|
||||
elif len(points) < 3:
|
||||
p1 = [points[0].x(), points[0].y()]
|
||||
p2 = [points[1].x(), points[1].y()]
|
||||
dimension = self.distance(p1, p2)
|
||||
scale = 0.001
|
||||
print(dimension * scale)
|
||||
f = sphere(dimension * scale)"""
|
||||
|
||||
if f:
|
||||
f.save('out.stl', samples=2**12, sparse=False)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication([])
|
||||
|
Loading…
x
Reference in New Issue
Block a user