diff --git a/Gui.py b/Gui.py
index 79fd224..fd264eb 100644
--- a/Gui.py
+++ b/Gui.py
@@ -242,23 +242,29 @@ class Ui_fluencyCAD(object):
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.pb_rectool = QPushButton(self.groupBox_2)
self.pb_rectool.setObjectName(u"pb_rectool")
+ self.pb_rectool.setCheckable(True)
+ self.pb_rectool.setAutoExclusive(False)
self.gridLayout_2.addWidget(self.pb_rectool, 1, 1, 1, 1, Qt.AlignTop)
self.pb_circtool = QPushButton(self.groupBox_2)
self.pb_circtool.setObjectName(u"pb_circtool")
+ self.pb_circtool.setCheckable(True)
+ self.pb_circtool.setAutoExclusive(False)
self.gridLayout_2.addWidget(self.pb_circtool, 2, 0, 1, 1, Qt.AlignTop)
self.pb_slotool = QPushButton(self.groupBox_2)
self.pb_slotool.setObjectName(u"pb_slotool")
+ self.pb_slotool.setCheckable(True)
+ self.pb_slotool.setAutoExclusive(False)
self.gridLayout_2.addWidget(self.pb_slotool, 2, 1, 1, 1, Qt.AlignTop)
self.pb_linetool = QPushButton(self.groupBox_2)
self.pb_linetool.setObjectName(u"pb_linetool")
self.pb_linetool.setCheckable(True)
- self.pb_linetool.setAutoExclusive(True)
+ self.pb_linetool.setAutoExclusive(False)
self.gridLayout_2.addWidget(self.pb_linetool, 1, 0, 1, 1)
@@ -274,25 +280,46 @@ class Ui_fluencyCAD(object):
self.pb_con_line = QPushButton(self.groupBox_3)
self.pb_con_line.setObjectName(u"pb_con_line")
self.pb_con_line.setCheckable(True)
+ self.pb_con_line.setAutoExclusive(False)
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.pb_con_ptpt.setCheckable(True)
+ self.pb_con_ptpt.setAutoExclusive(False)
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.pb_con_horiz.setCheckable(True)
+ self.pb_con_horiz.setAutoExclusive(False)
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.pb_con_vert.setCheckable(True)
+ self.pb_con_vert.setAutoExclusive(False)
self.gridLayout_4.addWidget(self.pb_con_vert, 1, 1, 1, 1)
+ self.pb_con_dist = QPushButton(self.groupBox_3)
+ self.pb_con_dist.setObjectName(u"pb_con_dist")
+ self.pb_con_dist.setCheckable(True)
+ self.pb_con_dist.setAutoExclusive(False)
+ self.pb_con_dist.setAutoRepeatDelay(297)
+
+ self.gridLayout_4.addWidget(self.pb_con_dist, 2, 0, 1, 1)
+
+ self.pb_con_sym = QPushButton(self.groupBox_3)
+ self.pb_con_sym.setObjectName(u"pb_con_sym")
+ self.pb_con_sym.setCheckable(True)
+ self.pb_con_sym.setAutoExclusive(False)
+
+ self.gridLayout_4.addWidget(self.pb_con_sym, 2, 1, 1, 1)
+
self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1)
@@ -352,5 +379,7 @@ class Ui_fluencyCAD(object):
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.pb_con_dist.setText(QCoreApplication.translate("fluencyCAD", u"Distnce", None))
+ self.pb_con_sym.setText(QCoreApplication.translate("fluencyCAD", u"Symetrc", None))
# retranslateUi
diff --git a/drawing_modules/draw_widget2d.py b/drawing_modules/draw_widget2d.py
index d073778..e9fcc96 100644
--- a/drawing_modules/draw_widget2d.py
+++ b/drawing_modules/draw_widget2d.py
@@ -1,14 +1,21 @@
+import math
import re
from copy import copy
-from PySide6.QtWidgets import QApplication, QWidget, QMessageBox
+from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QInputDialog
from PySide6.QtGui import QPainter, QPen, QColor
-from PySide6.QtCore import Qt, QPoint
+from PySide6.QtCore import Qt, QPoint, QPointF, Signal
from python_solvespace import SolverSystem, ResultFlag
class SketchWidget(QWidget):
+ constrain_done = Signal()
+
def __init__(self):
super().__init__()
+
+ self.zoom = 1
+ self.selected_main_idx = None
+ self.pt_line_buffer = None
self.hovered_point = None
self.line_buffer = None
self.pt_pt_buffer = None
@@ -21,7 +28,12 @@ class SketchWidget(QWidget):
self.wp = None
self.solv = SolverSystem()
- self.solventies = []
+ self.slv_points_main = []
+ self.slv_lines_main = []
+
+ def set_points(self, points: list):
+ self.points = points
+ #self.update()
def create_worplane(self):
self.wp = self.solv.create_2d_base()
@@ -36,12 +48,10 @@ class SketchWidget(QWidget):
if match:
handle_number = int(match.group(1))
print(f"Handle number: {handle_number}")
-
return int(handle_number)
else:
print("Handle number not found.")
-
return 0
def get_keys(self, d: dict, target: QPoint) -> list:
@@ -59,156 +69,539 @@ class SketchWidget(QWidget):
return result
+ def distance(self, p1, p2):
+ return math.sqrt((p1.x() - p2.x())**2 + (p1.y() - p2.y())**2)
+
+ def is_point_on_line(self, p, p1, p2, tolerance=5):
+ # Calculate the lengths of the sides of the triangle
+ a = self.distance(p, p1)
+ b = self.distance(p, p2)
+ c = self.distance(p1, p2)
+
+ # Calculate the semi-perimeter
+ s = (a + b + c) / 2
+
+ # Calculate the area using Heron's formula
+ area = math.sqrt(s * (s - a) * (s - b) * (s - c))
+
+ # Calculate the height (perpendicular distance from the point to the line)
+ if c > 0:
+ height = (2 * area) / c
+ # Check if the height is within the tolerance distance to the line
+ if height > tolerance:
+ return False
+
+ # Check if the projection of the point onto the line is within the line segment
+ dot_product = ((p.x() - p1.x()) * (p2.x() - p1.x()) + (p.y() - p1.y()) * (p2.y() - p1.y())) / (c ** 2)
+
+ return 0 <= dot_product <= 1
+ else:
+ return None
+ def viewport_to_local_coord(self, qt_pos : QPoint) -> QPoint:
+ self.to_quadrant_coords(qt_pos)
+ return QPoint(self.to_quadrant_coords(qt_pos))
+
def mousePressEvent(self, event):
- relation = {
+ local_event_pos = self.viewport_to_local_coord(event.pos())
+
+ def check_all_points() -> list:
+ old_points_ui = []
+ new_points_ui = []
+
+ for old_point_ui in self.slv_points_main:
+ old_points_ui.append(old_point_ui['ui_point'])
+
+ for i in range(len(self.slv_points_main) + len(self.slv_lines_main)):
+ #Iterate though full length because mixed list from SS
+ entity = self.solv.entity(i)
+ if entity.is_point_2d() and self.solv.params(entity.params):
+ x_tbu, y_tbu = self.solv.params(entity.params)
+ point_solved = QPoint(x_tbu, y_tbu)
+ new_points_ui.append(point_solved)
+
+ # Now we have old_points_ui and new_points_ui, let's compare them
+ differences = []
+
+ if len(old_points_ui) != len(new_points_ui) +1 :
+ differences.append(f"Length mismatch {len(old_points_ui)} - {len(new_points_ui)}")
+ return differences
+
+ for index, (old_point, new_point) in enumerate(zip(old_points_ui, new_points_ui)):
+ if old_point != new_point:
+ differences.append((index, old_point, new_point))
+
+ return differences
+
+ def update_ui_points(point_list: list):
+ # Print initial state of slv_points_main
+ """print("Initial slv_points_main:", self.slv_points_main)
+ print("Change list:", point_list)"""
+
+ for tbu_points_idx in point_list:
+ # Each tbu_points_idx is a tuple: (index, old_point, new_point)
+ index, old_point, new_point = tbu_points_idx
+ """print("Updating index:", index)
+ print("Old point:", old_point)
+ print("New point:", new_point)"""
+
+ # Update the point in slv_points_main
+ self.slv_points_main[index]['ui_point'] = new_point
+
+ # Print updated state
+ #print("Updated slv_points_main:", self.slv_points_main)
+
+ """# UPDATE UI POINTS with solver points
+ for i in range(len(self.slv_points_main) + len(self.slv_lines_main)):
+ entity = self.solv.entity(i)
+ if entity.is_point_2d() and self.solv.params(entity.params):
+ x_tbu, y_tbu = self.solv.params(entity.params)
+ point_solved = QPoint(x_tbu, y_tbu)
+ for point_to_be_updated in self.slv_points_main:
+ #print("Checking point:", point_to_be_updated)
+ # if the old ui point is present in the selected constrain line
+ # update the _ui_point with solver_point
+
+ if point_to_be_updated['ui_point'] == target_line_con['ui_points'][0]:
+ print("that got updated", point_solved)
+ point_to_be_updated['ui_point'] = point_solved
+
+ elif point_to_be_updated['ui_point'] == target_line_con['ui_points'][1]:
+ print("this got updated", point_solved)
+ point_to_be_updated['ui_point'] = point_solved
+
+ if point_to_be_updated['ui_point'] == target_line_con['ui_points'][0]:
+ target_line_con['ui_points'][0] = point_solved
+
+ elif point_to_be_updated['ui_point'] == target_line_con['ui_points'][1]:
+ target_line_con['ui_points'][1] = point_solved
+
+ #TODO: All points ui and solve into lists and then check before afer for changes
+ # and update displayed points and then lines"""
+
+ def check_all_lines_and_update(changed_points: list):
+ for tbu_points_idx in changed_points:
+ index, old_point, new_point = tbu_points_idx
+ for line_needs_update in self.slv_lines_main:
+ if old_point == line_needs_update['ui_points'][0]:
+ line_needs_update['ui_points'][0] = new_point
+ elif old_point == line_needs_update['ui_points'][1]:
+ line_needs_update['ui_points'][1] = new_point
+
+ relation_point = {
'handle_nr': None,
- 'solv_handle': None
+ 'solv_handle': None,
+ 'ui_point': None,
+ 'part_of_entity': None
+ }
+
+ relation_line = {
+ 'handle_nr': None,
+ 'solv_handle': None,
+ 'solv_entity_points': None,
+ 'ui_points': None
}
if event.button() == Qt.LeftButton and self.mouse_mode == "line":
- clicked_pos = event.pos()
+ clicked_pos = local_event_pos
# Paintline
"""self.points.append(clicked_pos)
self.update()"""
u = clicked_pos.x()
v = clicked_pos.y()
+
point = self.solv.add_point_2d(u, v, self.wp)
- #print(point)
- #self.solv.dragged(point, self.wp)
+
+ # Track Relationship
+ # Points
+ handle_nr = self.get_handle_nr(str(point))
+ relation_point['handle_nr'] = handle_nr
+ relation_point['solv_handle'] = point
+ relation_point['ui_point'] = clicked_pos
+
+ # List of points related to the current "figure"
+ self.points.append(clicked_pos)
# Solverline
if self.line_buffer:
line = self.solv.add_line_2d(self.line_buffer, point, self.wp)
- #print(line)
+ handle_nr_line = self.get_handle_nr(str(line))
+ relation_line['handle_nr'] = handle_nr_line
+ relation_line['solv_handle'] = line
+ relation_line['solv_entity_points'] = (self.line_buffer, point)
+ relation_line['ui_points'] = [self.points[-2], self.points[-1]]
+
+ #track relationship of point in line
+ relation_point['part_of_entity'] = handle_nr_line
+
+ self.slv_lines_main.append(relation_line)
+
+ self.slv_points_main.append(relation_point)
self.line_buffer = point
- # Track Relationship
- handle_nr = self.get_handle_nr(str(point))
- relation['handle_nr'] = handle_nr
- relation['solv_handle'] = point
- relation['ui_point'] = clicked_pos
-
- self.solventies.append(relation)
-
- self.points.append(clicked_pos)
-
- print(self.points)
+ print("points", self.slv_points_main)
+ print("lines", self.slv_lines_main)
if event.button() == Qt.LeftButton and self.mouse_mode == "pt_pt":
- #point_solve_now = self.solventies[self.hovered_point]['solv_handle']
-
- for new_id, entry in enumerate(self.solventies):
- if self.hovered_point == entry['ui_point']:
- point_solve_now = entry['solv_handle']
- print(point_solve_now)
- target_id = new_id
+ point_solve_old = None
+ point_solve_now = None
if self.pt_pt_buffer:
- for old_id, entry in enumerate(self.solventies):
- if self.pt_pt_buffer == entry['ui_point']:
- point_solve_old = entry['solv_handle']
+ for new_id, target_line in enumerate(self.slv_points_main):
+ if self.hovered_point == target_line['ui_point']:
+ point_solve_now = target_line['solv_handle']
+ target_id = new_id
+ break
+ else:
+ point_solve_now = None
+
+ for old_id, target_line in enumerate(self.slv_points_main):
+ if self.pt_pt_buffer == target_line['ui_point']:
+ point_solve_old = target_line['solv_handle']
move_id = old_id
+ break
+ else:
+ point_solve_old = None
- #point_solve_old = self.solventies[self.pt_pt_buffer]['solv_handle']
- #self.solv.dragged(point_solve_now, self.wp)
- self.solv.coincident(point_solve_now, point_solve_old, self.wp)
+ if point_solve_old and point_solve_now:
+ self.solv.coincident(point_solve_now, point_solve_old, self.wp)
- if self.solv.solve() == ResultFlag.OKAY:
- # Get the result (unpack from the entity or parameters)
- # x and y are actually float type
- dof = self.solv.dof()
- print(dof)
- print(self.solventies[move_id]['ui_point'])
- print(self.solventies[target_id]['ui_point'])
- x, y = self.solv.params(self.solventies[move_id]['solv_handle'].params)
- self.solventies[move_id]['ui_point'] = QPoint(x, y)
+ if self.solv.solve() == ResultFlag.OKAY:
- print(f"{x}, {y}")
- print(self.solventies) #after adding the result
+ """x, y = self.solv.params(self.slv_points_main[move_id]['solv_handle'].params)
+ moved_point = QPoint(x, y)
+ self.slv_points_main[target_id]['ui_point'] = moved_point
- elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
- print("Solve_failed - Converge" )
+ for ident, lines in enumerate(self.slv_lines_main):
+ if self.slv_points_main[target_id]['solv_handle'] == lines['solv_entity_points'][0]:
+ self.slv_lines_main[ident]['ui_points'][0] = moved_point"""
- elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
- print("Solve_failed - Unknowns" )
+ self.pt_pt_buffer = []
+ self.constrain_done.emit()
+ #print(dof)
+ self.update()
- elif self.solv.solve() == ResultFlag.INCONSISTENT:
- print("Solve_failed - Incons" )
+ elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
+ print("Solve_failed - Converge" )
- self.points = []
- for points_ui in self.solventies:
- self.points.append(points_ui['ui_point'])
- print(self.points)
+ elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
+ print("Solve_failed - Unknowns" )
+
+ elif self.solv.solve() == ResultFlag.INCONSISTENT:
+ print("Solve_failed - Incons" )
+
+ self.points = []
+
+ #for points_ui in self.slv_points_main:
+ #self.points.append(points_ui['ui_point'])
+ print(self.points)
+ print("Points_all", self.slv_points_main)
self.pt_pt_buffer = self.hovered_point
self.update()
-
+
+ if event.button() == Qt.LeftButton and self.mouse_mode == "pt_line":
+ print("ptline")
+ line_selected = None
+
+ if self.hovered_point:
+ for nr, entry_point in enumerate(self.slv_points_main):
+ if self.hovered_point == entry_point['ui_point']:
+ self.pt_line_buffer = entry_point
+ self.selected_main_idx = nr
+ print("Point set", self.pt_line_buffer)
+ break
+
+ if self.pt_line_buffer:
+ #Line selection target_line to constrain to
+ for target_line_con in self.slv_lines_main:
+ if self.is_point_on_line(local_event_pos, target_line_con['ui_points'][0], target_line_con['ui_points'][1]):
+ line_selected = target_line_con['solv_handle']
+ print(line_selected.params)
+ break
+
+ #Update UI Line position ot the line of the selected point
+ for line_nr, move_line in enumerate(self.slv_lines_main):
+ #Test what point is going to be moved from the line
+ if move_line['ui_points'][0] == self.pt_line_buffer['ui_point']:
+ print("On line", line_nr)
+ idx = 0
+ break
+
+ elif move_line['ui_points'][1] == self.pt_line_buffer['ui_point']:
+ print("On line", line_nr)
+ idx = 1
+ break
+
+ # Contrain point to line
+ if line_selected:
+ self.solv.coincident(self.pt_line_buffer['solv_handle'], line_selected, self.wp)
+ print(f"1 : {self.pt_line_buffer['solv_handle']}, 2: {line_selected}")
+
+ if self.solv.solve() == ResultFlag.OKAY:
+ print("Fuck yeah")
+ x, y = self.solv.params(self.pt_line_buffer['solv_handle'].params)
+
+ #Update UI points to returned points from solver
+ self.slv_points_main[self.selected_main_idx]['ui_point'] = QPoint(x, y)
+ self.slv_lines_main[line_nr]['ui_points'][idx] = QPoint(x, y)
+
+ self.pt_line_buffer = None
+ self.constrain_done.emit()
+
+ elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
+ print("Solve_failed - Converge")
+
+ elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
+ print("Solve_failed - Unknowns")
+
+ elif self.solv.solve() == ResultFlag.INCONSISTENT:
+ print("Solve_failed - Incons")
+
+ if event.button() == Qt.LeftButton and self.mouse_mode == "horiz":
+
+ for target_line_con in self.slv_lines_main:
+ if self.is_point_on_line(local_event_pos, target_line_con['ui_points'][0], target_line_con['ui_points'][1]):
+ line_selected = target_line_con['solv_handle']
+ print(line_selected.params)
+ break
+
+ self.solv.horizontal(line_selected, self.wp)
+
+ if self.solv.solve() == ResultFlag.OKAY:
+ print("Fuck yeah")
+
+ self.pt_line_buffer = None
+ self.constrain_done.emit()
+
+ elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
+ print("Solve_failed - Converge")
+
+ elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
+ print("Solve_failed - Unknowns")
+
+ elif self.solv.solve() == ResultFlag.INCONSISTENT:
+ print("Solve_failed - Incons")
+
+ if event.button() == Qt.LeftButton and self.mouse_mode == "vert":
+
+ for target_line_con in self.slv_lines_main:
+ if self.is_point_on_line(local_event_pos, target_line_con['ui_points'][0], target_line_con['ui_points'][1]):
+ line_selected = target_line_con['solv_handle']
+ print(line_selected.params)
+ break
+
+ self.solv.vertical(line_selected, self.wp)
+
+ if self.solv.solve() == ResultFlag.OKAY:
+ print("Fuck yeah")
+
+ self.pt_line_buffer = None
+ self.constrain_done.emit()
+
+ elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
+ print("Solve_failed - Converge")
+
+ elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
+ print("Solve_failed - Unknowns")
+
+ elif self.solv.solve() == ResultFlag.INCONSISTENT:
+ print("Solve_failed - Incons")
+
+ if event.button() == Qt.LeftButton and self.mouse_mode == "distance":
+ print("distance")
+
+ for target_line_con in self.slv_lines_main:
+ if self.is_point_on_line(local_event_pos, target_line_con['ui_points'][0], target_line_con['ui_points'][1]):
+ lines_to_cons = target_line_con['solv_entity_points']
+ break
+ length, ok = QInputDialog.getDouble(self, 'Distance', 'Enter a mm value:', decimals=2)
+ e1, e2 = lines_to_cons
+
+ self.solv.distance(e1, e2, length, self.wp)
+
+ if self.solv.solve() == ResultFlag.OKAY:
+ print("Fuck yeah")
+
+ self.pt_line_buffer = None
+ self.constrain_done.emit()
+
+ elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE:
+ print("Solve_failed - Converge")
+
+ elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS:
+ print("Solve_failed - Unknowns")
+
+ elif self.solv.solve() == ResultFlag.INCONSISTENT:
+ print("Solve_failed - Incons")
+
+
+ points_need_update = check_all_points()
+ print("This", points_need_update)
+ update_ui_points(points_need_update)
+
+ lines_need_update = check_all_lines_and_update(points_need_update)
+ print("This", lines_need_update)
+
+ dof = self.solv.dof()
+ print(dof)
+
+ self.update()
+
def mouseMoveEvent(self, event):
+ local_event_pos = self.viewport_to_local_coord(event.pos())
+
closest_point = None
min_distance = float('inf')
threshold = 10 # Distance threshold for highlighting
- for point in self.points:
- distance = (event.pos() - point).manhattanLength()
+ for point in self.slv_points_main:
+ distance = (local_event_pos - point['ui_point']).manhattanLength()
if distance < threshold and distance < min_distance:
- closest_point = point
+ closest_point = point['ui_point']
min_distance = distance
if closest_point != self.hovered_point:
self.hovered_point = closest_point
- self.update()
+ print(self.hovered_point)
+
+ selected_points = []
+
+ for dic in self.slv_lines_main:
+ p1 = dic['ui_points'][0]
+ p2 = dic['ui_points'][1]
+
+ if self.is_point_on_line(local_event_pos, p1, p2):
+ self.selected_line = p1, p2
+ break
+ else:
+ self.selected_line = None
+
+ self.update()
def mouseDoubleClickEvent(self, event):
pass
- def distance(self, p1, p2):
- return ((p1.x() - p2.x()) ** 2 + (p1.y() - p2.y()) ** 2) ** 0.5
+ def drawBackgroundGrid(self, painter):
+ """Draw a background grid."""
+ grid_spacing = 50
+ pen = QPen(QColor(200, 200, 200), 1, Qt.SolidLine)
+ painter.setPen(pen)
- def set_points(self, points: list):
- self.points = points
- #self.update()
+ # Draw vertical grid lines
+ for x in range(-self.width() // 2, self.width() // 2, grid_spacing):
+ painter.drawLine(x, -self.height() // 2, x, self.height() // 2)
- def is_point_on_line(self, p, p1, p2):
- distance1 = self.distance(p, p1)
- distance2 = self.distance(p, p2)
- total_distance = self.distance(p1, p2)
+ # Draw horizontal grid lines
+ for y in range(-self.height() // 2, self.height() // 2, grid_spacing):
+ painter.drawLine(-self.width() // 2, y, self.width() // 2, y)
- return abs(distance1 + distance2 - total_distance) < 1
+ def drawAxes(self, painter):
+ painter.setRenderHint(QPainter.Antialiasing)
+
+ # Set up pen for dashed lines
+ pen = QPen(Qt.gray, 1, Qt.DashLine)
+ painter.setPen(pen)
+
+ middle_x = self.width() // 2
+ middle_y = self.height() // 2
+
+ # Draw X axis as dashed line
+ painter.drawLine(0, middle_y, self.width(), middle_y)
+
+ # Draw Y axis as dashed line
+ painter.drawLine(middle_x, 0, middle_x, self.height())
+
+ # Draw tick marks
+ tick_length = 10
+ tick_spacing = 50
+
+ pen = QPen(Qt.gray, 1, Qt.SolidLine)
+ painter.setPen(pen)
+
+ # Draw tick marks on the X axis
+ for x in range(0, self.width(), tick_spacing):
+ painter.drawLine(x, middle_y - tick_length // 2, x, middle_y + tick_length // 2)
+
+ # Draw tick marks on the Y axis
+ for y in range(0, self.height(), tick_spacing):
+ painter.drawLine(middle_x - tick_length // 2, y, middle_x + tick_length // 2, y)
+
+ # Draw the origin point in red
+ painter.setPen(QPen(Qt.red, 4))
+ painter.drawPoint(middle_x, middle_y)
+
+ def to_quadrant_coords(self, point):
+ """Translate linear coordinates to quadrant coordinates."""
+ center_x = self.width() // 2
+ center_y = self.height() // 2
+ quadrant_x = point.x() - center_x
+ quadrant_y = point.y() - center_y
+ return QPoint(quadrant_x, quadrant_y) / self.zoom
def paintEvent(self, event):
painter = QPainter(self)
+ #self.drawBackgroundGrid(painter)
+ self.drawAxes(painter)
+
+ # Translate the origin to the center of the widget
+ center = QPoint(self.width() // 2, self.height() // 2)
+ painter.translate(center)
+
+ # Apply the zoom factor
+ painter.scale(self.zoom, self.zoom)
+
# Set the background color
- painter.fillRect(self.rect(), QColor('black'))
+ #painter.fillRect(0, self.width(), 0, self.height(), QColor('black'))
+
+ # Draw axes
pen = QPen(Qt.gray)
- pen.setWidth(2)
+ pen.setWidth(2 / self.zoom)
painter.setPen(pen)
# Draw points
- for point in self.points:
- painter.drawEllipse(point, 3, 3)
+ for point in self.slv_points_main:
+ painter.drawEllipse(point['ui_point'], 3 / self.zoom, 3 / self.zoom)
- if len (self.points) > 0:
- for i in range(len(self.points)-1):
- painter.drawLine(self.points[i], self.points[i + 1])
+ for dic in self.slv_lines_main:
+ painter.drawLine(dic['ui_points'][0] , dic['ui_points'][1])
+
+ pen = QPen(Qt.green)
+ pen.setWidth(2)
+ painter.setPen(pen)
+
+ for i in range(len(self.slv_points_main) + len(self.slv_lines_main)):
+ entity = self.solv.entity(i)
+ if entity.is_point_2d() and self.solv.params(entity.params):
+ x,y = self.solv.params(entity.params)
+ point = QPoint(x, y)
+ painter.drawEllipse(point, 6 / self.zoom, 6 / self.zoom)
#Highlight point hovered
if self.hovered_point:
highlight_pen = QPen(QColor(255, 0, 0))
highlight_pen.setWidth(2)
painter.setPen(highlight_pen)
- painter.drawEllipse(self.hovered_point, 5, 5)
+ painter.drawEllipse(self.hovered_point, 5 / self.zoom, 5 / self.zoom)
- """if self.selected_line is not None:
- p1 = self.points[self.selected_line]
- p2 = self.points[self.selected_line + 1]
+ if self.selected_line:
+ p1, p2 = self.selected_line
painter.setPen(QPen(Qt.red, 2))
- painter.drawLine(p1, p2)"""
+ painter.drawLine(p1, p2)
+
painter.end()
+ def wheelEvent(self, event):
+ delta = event.angleDelta().y()
+ self.zoom += (delta / 200) * 0.1
+ self.update()
+
+ def aspect_ratio(self):
+ return self.width() / self.height() * (1.0 / abs(self.zoom))
+
def clear_sketch(self):
self.points = []
self.update()
diff --git a/drawing_modules/gl_widget.py b/drawing_modules/gl_widget.py
index e762cce..2a0ea4c 100644
--- a/drawing_modules/gl_widget.py
+++ b/drawing_modules/gl_widget.py
@@ -28,7 +28,6 @@ class OpenGLWidget(QOpenGLWidget):
return mapped_value
-
def load_stl(self, filename: str) -> object:
try:
stl_mesh = mesh.Mesh.from_file(filename)
@@ -76,12 +75,10 @@ class OpenGLWidget(QOpenGLWidget):
def clear_mesh(self):
self.mesh_loaded = None
-
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)
diff --git a/gui.ui b/gui.ui
index f55828b..417e23d 100644
--- a/gui.ui
+++ b/gui.ui
@@ -331,6 +331,12 @@
Rctgl
+
+ true
+
+
+ false
+
-
@@ -338,6 +344,12 @@
Circle
+
+ true
+
+
+ false
+
-
@@ -345,6 +357,12 @@
Slot
+
+ true
+
+
+ false
+
-
@@ -356,7 +374,7 @@
true
- true
+ false
@@ -383,6 +401,9 @@
true
+
+ false
+
-
@@ -393,6 +414,9 @@
true
+
+ false
+
-
@@ -400,6 +424,12 @@
Horiz
+
+ true
+
+
+ false
+
-
@@ -407,6 +437,41 @@
Vert
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ Distnce
+
+
+ true
+
+
+ false
+
+
+ 297
+
+
+
+ -
+
+
+ Symetrc
+
+
+ true
+
+
+ false
+
diff --git a/main.py b/main.py
index 056f9e0..9d66abc 100644
--- a/main.py
+++ b/main.py
@@ -53,12 +53,19 @@ class MainWindow(QMainWindow):
###Modes
self.ui.pb_linetool.pressed.connect(self.act_line_mode)
self.ui.pb_con_ptpt.pressed.connect(self.act_constrain_pt_pt_mode)
+ self.ui.pb_con_line.pressed.connect(self.act_constrain_pt_line_mode)
+ self.ui.pb_con_horiz.pressed.connect(self.act_constrain_horiz_line_mode)
+ self.ui.pb_con_vert.pressed.connect(self.act_constrain_vert_line_mode)
+ self.ui.pb_con_dist.pressed.connect(self.act_constrain_distance_mode)
### Operations
self.ui.pb_extrdop.pressed.connect(self.send_extrude)
self.ui.pb_cutop.pressed.connect(self.send_cut)
self.ui.pb_del_body.pressed.connect(self.del_body)
+ self.sketchWidget.constrain_done.connect(self.constrain_finished)
+
+
def add_wp_origin(self):
#Select orientation
#orientation, ok = Q .getDouble(self, 'Extrude Length', 'Enter a mm value:', decimals=2)
@@ -70,14 +77,48 @@ class MainWindow(QMainWindow):
#self.sketchWidget.points = []
else:
self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+ self.sketchWidget.points = []
def act_constrain_pt_pt_mode(self):
if not self.ui.pb_linetool.isChecked():
self.sketchWidget.mouse_mode = 'pt_pt'
- #self.sketchWidget.points = []
else:
self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+ def act_constrain_pt_line_mode(self):
+ if not self.ui.pb_linetool.isChecked():
+ self.sketchWidget.mouse_mode = 'pt_line'
+ else:
+ self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+
+ def act_constrain_horiz_line_mode(self):
+ if not self.ui.pb_con_horiz.isChecked():
+ self.sketchWidget.mouse_mode = 'horiz'
+ else:
+ self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+
+ def act_constrain_vert_line_mode(self):
+ if not self.ui.pb_con_vert.isChecked():
+ self.sketchWidget.mouse_mode = 'vert'
+ else:
+ self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+
+ def act_constrain_distance_mode(self):
+ if not self.ui.pb_con_vert.isChecked():
+ self.sketchWidget.mouse_mode = 'distance'
+ else:
+ self.sketchWidget.mouse_mode = None
+ self.sketchWidget.line_buffer = None
+
+ def constrain_finished(self):
+ self.ui.pb_con_ptpt.setChecked(False)
+ self.ui.pb_con_line.setChecked(False)
+ self.ui.pb_con_dist.setChecked(False)
def view_update(self):
print("Update")
@@ -192,6 +233,9 @@ class MainWindow(QMainWindow):
# UI to mesh
points = self.translate_points_tup(points)
+ if points[-1] == points[0]:
+ result = points.pop()
+ print("removed last point for mesh")
length , ok = QInputDialog.getDouble(self, 'Extrude Length', 'Enter a mm value:', decimals=2)
#TODO : Implement cancel
@@ -310,4 +354,6 @@ if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
- app.exec()
\ No newline at end of file
+ app.exec()
+
+ #pyside6-uic gui.ui > Gui.py -g python
\ No newline at end of file