From f26a59615928a84373d69b540ae63d95136427fd Mon Sep 17 00:00:00 2001 From: bklronin Date: Fri, 28 Mar 2025 21:17:19 +0100 Subject: [PATCH] - Added contrain displayed next to line - Slight change to point check from solver. --- drawing_modules/draw_widget_solve.py | 247 +++++++++++++++++---------- requirements.txt | 102 ++++++----- 2 files changed, 209 insertions(+), 140 deletions(-) diff --git a/drawing_modules/draw_widget_solve.py b/drawing_modules/draw_widget_solve.py index fe8fc3a..2386485 100644 --- a/drawing_modules/draw_widget_solve.py +++ b/drawing_modules/draw_widget_solve.py @@ -269,11 +269,12 @@ class SketchWidget(QWidget): Go through solversystem and check points2d for changes in position after solving :return: List with points that now have a different position """ + old_points_ui = [] new_points_ui = [] - for old_point_ui in self.sketch.points: - old_points_ui.append(old_point_ui.ui_point) + for index, old_point_ui in enumerate(self.sketch.points): + old_points_ui.append((index, old_point_ui.ui_point)) for i in range(self.sketch.entity_len()): # Iterate though full length because mixed list from SS @@ -289,24 +290,32 @@ class SketchWidget(QWidget): if len(old_points_ui) != len(new_points_ui): print(f"Length mismatch {len(old_points_ui)} - {len(new_points_ui)}") - for index, (old_point, new_point) in enumerate(zip(old_points_ui, new_points_ui)): + for (old_index, old_point), new_point in zip(old_points_ui, new_points_ui): if old_point != new_point: - differences.append((index, old_point, new_point)) + print(old_point) + differences.append((old_index, old_point, new_point)) return differences def update_ui_points(self, point_list: list): # Print initial state of slv_points_main # print("Initial slv_points_main:", self.slv_points_main) - #print("Change list:", point_list) + print("Change list:", point_list) - if len(point_list) > 0: + """for point in point_list: + new = Point2D(point.x(), point.y()) + self.sketch.points.append(new)""" + + if len(point_list) > 1: 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 # Update the point in slv_points_main self.sketch.points[index].ui_point = new_point + + for points in self.sketch.points: + print(points.ui_point) # Print updated state # print("Updated slv_points_main:", self.slv_points_main) @@ -334,9 +343,9 @@ class SketchWidget(QWidget): self.sketch.solve() - points_need_update = self.check_all_points() - self.update_ui_points(points_need_update) - self.check_all_lines_and_update(points_need_update) + #points_need_update = self.check_all_points() + #self.update_ui_points(points_need_update) + #self.check_all_lines_and_update(points_need_update) self.update() self.drag_buffer = [None, None] @@ -468,6 +477,7 @@ class SketchWidget(QWidget): #print("ptline") line_selected = None + if self.hovered_point and not self.main_buffer[1]: self.main_buffer[0] = self.get_handle_from_ui_point(self.hovered_point) @@ -480,6 +490,12 @@ class SketchWidget(QWidget): if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") + for idx, line in enumerate(self.sketch.lines): + # print(line.crd1.ui_point) + if self.is_point_on_line(local_event_pos, line.crd1.ui_point, line.crd2.ui_point): + self.sketch.lines[idx].constraints.append("mid") + print(self.sketch.lines[idx].constraints) + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") @@ -497,12 +513,21 @@ class SketchWidget(QWidget): line_selected = self.get_line_handle_from_ui_point(local_event_pos) + + if line_selected: self.sketch.horizontal(line_selected, self.sketch.wp) if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") + # Add succesful constraint to constrain draw list so it gets drawn in paint function + for idx, line in enumerate(self.sketch.lines): + print(line.crd1.ui_point) + if self.is_point_on_line(local_event_pos, line.crd1.ui_point, line.crd2.ui_point): + self.sketch.lines[idx].constraints.append("hrz") + print(self.sketch.lines[idx].constraints) + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") @@ -515,11 +540,18 @@ class SketchWidget(QWidget): if event.button() == Qt.LeftButton and self.mouse_mode == "vert": line_selected = self.get_line_handle_from_ui_point(local_event_pos) + + if line_selected: self.sketch.vertical(line_selected, self.sketch.wp) if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") + for idx, line in enumerate(self.sketch.lines): + # print(line.crd1.ui_point) + if self.is_point_on_line(local_event_pos, line.crd1.ui_point, line.crd2.ui_point): + self.sketch.lines[idx].constraints.append("vrt") + # print(self.sketch.lines[idx].constraints) elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") @@ -536,6 +568,8 @@ class SketchWidget(QWidget): e1 = None e2 = None + + if self.hovered_point: # print("buf point") # Get the point as UI point as buffer @@ -561,6 +595,11 @@ class SketchWidget(QWidget): if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") + for idx, line in enumerate(self.sketch.lines): + # print(line.crd1.ui_point) + if self.is_point_on_line(local_event_pos, line.crd1.ui_point, line.crd2.ui_point): + if "dist" not in self.sketch.lines[idx].constraints: + self.sketch.lines[idx].constraints.append("dst") elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") @@ -579,6 +618,8 @@ class SketchWidget(QWidget): self.update_ui_points(points_need_update) self.check_all_lines_and_update(points_need_update) + + self.update() def mouseMoveEvent(self, event): @@ -725,6 +766,103 @@ class SketchWidget(QWidget): widget_y = -point.y() return QPoint(int(widget_x), int(widget_y)) + def draw_measurement(self,painter, start_point, end_point): + + pen_normal = QPen(Qt.gray) + pen_normal.setWidthF(2 / self.zoom) + + pen_planned = QPen(Qt.gray) + pen_planned.setStyle(Qt.PenStyle.DotLine) + pen_planned.setWidthF(2 / self.zoom) + + pen_construct = QPen(Qt.cyan) + pen_construct.setStyle(Qt.PenStyle.DotLine) + pen_construct.setWidthF(1 / self.zoom) + + pen_solver = QPen(Qt.green) + pen_solver.setWidthF(2 / self.zoom) + + pen_text = QPen(Qt.white) + pen_text.setWidthF(1 / self.zoom) + + # Calculate the direction of the line + dx = end_point.x() - start_point.x() + dy = end_point.y() - start_point.y() + + # Swap and negate to get a perpendicular vector + perp_dx = -dy + perp_dy = dx + + # Normalize the perpendicular vector + length = (perp_dx ** 2 + perp_dy ** 2) ** 0.5 + if length == 0: # Prevent division by zero + return + perp_dx /= length + perp_dy /= length + + # Fixed length for the perpendicular lines + fixed_length = 40 # Adjust as needed + half_length = fixed_length # fixed_length / 2 + + # Calculate endpoints for the perpendicular line at the start + start_perp_start_x = start_point.x() + perp_dx + start_perp_start_y = start_point.y() + perp_dy + + start_perp_end_x = start_point.x() + perp_dx * half_length * (1 / self.zoom) + start_perp_end_y = start_point.y() + perp_dy * half_length * (1 / self.zoom) + + start_perp_end_x_conn_line = start_point.x() + perp_dx * half_length * 0.75 * (1 / self.zoom) + start_perp_end_y_conn_line = start_point.y() + perp_dy * half_length * 0.75 * (1 / self.zoom) + + # Draw the perpendicular line at the start + painter.setPen(pen_construct) # Different color for the perpendicular line + painter.drawLine( + QPointF(start_perp_start_x, start_perp_start_y), + QPointF(start_perp_end_x, start_perp_end_y) + ) + + # Calculate endpoints for the perpendicular line at the end + end_perp_start_x = end_point.x() + perp_dx + end_perp_start_y = end_point.y() + perp_dy + + end_perp_end_x = end_point.x() + perp_dx * half_length * (1 / self.zoom) + end_perp_end_y = end_point.y() + perp_dy * half_length * (1 / self.zoom) + + end_perp_end_x_conn_line = end_point.x() + perp_dx * half_length * .75 * (1 / self.zoom) + end_perp_end_y_conn_line = end_point.y() + perp_dy * half_length * .75 * (1 / self.zoom) + + # Draw the perpendicular line at the end + painter.drawLine( + QPointF(end_perp_start_x, end_perp_start_y), + QPointF(end_perp_end_x, end_perp_end_y) + ) + + painter.drawLine( + QPointF(end_perp_end_x_conn_line, end_perp_end_y_conn_line), + QPointF(start_perp_end_x_conn_line, start_perp_end_y_conn_line) + ) + + # Save painter state + painter.save() + painter.setPen(pen_text) + + # Calculate the distance and midpoint + dis = self.distance(start_point, end_point) + mid = self.calculate_midpoint(QPointF(start_perp_end_x_conn_line, start_perp_end_y_conn_line), + QPointF(end_perp_end_x_conn_line, end_perp_end_y_conn_line)) + + # mid = self.calculate_midpoint(start_point, end_point) + + # Transform for text + painter.translate(mid.x(), mid.y()) # Move to the midpoint + painter.scale(1, -1) # Flip y-axis back to make text readable + + # Draw the text + painter.drawText(0, 0, str(round(dis, 2))) # Draw text at transformed position + + # Restore painter state + painter.restore() + def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) @@ -780,83 +918,7 @@ class SketchWidget(QWidget): painter.setPen(pen_planned) # Use a different color for the dynamic line painter.drawLine(start_point, end_point) - # Calculate the direction of the line - dx = end_point.x() - start_point.x() - dy = end_point.y() - start_point.y() - - # Swap and negate to get a perpendicular vector - perp_dx = -dy - perp_dy = dx - - # Normalize the perpendicular vector - length = (perp_dx ** 2 + perp_dy ** 2) ** 0.5 - if length == 0: # Prevent division by zero - return - perp_dx /= length - perp_dy /= length - - # Fixed length for the perpendicular lines - fixed_length = 40 # Adjust as needed - half_length = fixed_length #fixed_length / 2 - - # Calculate endpoints for the perpendicular line at the start - start_perp_start_x = start_point.x() + perp_dx - start_perp_start_y = start_point.y() + perp_dy - - start_perp_end_x = start_point.x() + perp_dx * half_length * (1 / self.zoom) - start_perp_end_y = start_point.y() + perp_dy * half_length * (1 / self.zoom) - - start_perp_end_x_conn_line = start_point.x() + perp_dx * half_length * 0.75 * (1 / self.zoom) - start_perp_end_y_conn_line = start_point.y() + perp_dy * half_length * 0.75 * (1 / self.zoom) - - # Draw the perpendicular line at the start - painter.setPen(pen_construct) # Different color for the perpendicular line - painter.drawLine( - QPointF(start_perp_start_x, start_perp_start_y), - QPointF(start_perp_end_x, start_perp_end_y) - ) - - # Calculate endpoints for the perpendicular line at the end - end_perp_start_x = end_point.x() + perp_dx - end_perp_start_y = end_point.y() + perp_dy - - end_perp_end_x = end_point.x() + perp_dx * half_length * (1 / self.zoom) - end_perp_end_y = end_point.y() + perp_dy * half_length * (1 / self.zoom) - - end_perp_end_x_conn_line = end_point.x() + perp_dx * half_length * .75 * (1 / self.zoom) - end_perp_end_y_conn_line = end_point.y() + perp_dy * half_length * .75 * (1 / self.zoom) - - - # Draw the perpendicular line at the end - painter.drawLine( - QPointF(end_perp_start_x, end_perp_start_y), - QPointF(end_perp_end_x, end_perp_end_y) - ) - - painter.drawLine( - QPointF(end_perp_end_x_conn_line, end_perp_end_y_conn_line), - QPointF(start_perp_end_x_conn_line, start_perp_end_y_conn_line) - ) - - # Save painter state - painter.save() - painter.setPen(pen_text) - - # Calculate the distance and midpoint - dis = self.distance(start_point, end_point) - mid = self.calculate_midpoint(QPointF(start_perp_end_x_conn_line, start_perp_end_y_conn_line), QPointF(end_perp_end_x_conn_line, end_perp_end_y_conn_line)) - - #mid = self.calculate_midpoint(start_point, end_point) - - # Transform for text - painter.translate(mid.x(), mid.y()) # Move to the midpoint - painter.scale(1, -1) # Flip y-axis back to make text readable - - # Draw the text - painter.drawText(0, 0, str(round(dis, 2))) # Draw text at transformed position - - # Restore painter state - painter.restore() + self.draw_measurement(painter, start_point, end_point) for line in self.sketch.lines: if line.is_helper: @@ -870,6 +932,16 @@ class SketchWidget(QWidget): p2 = line.crd2.ui_point painter.drawLine(p1, p2) + self.draw_measurement(painter, p1, p2) + painter.save() + midp = self.calculate_midpoint(p1, p2) + painter.translate(midp) + painter.scale(1, -1) + + for i, text in enumerate(line.constraints): + painter.drawText(0, i * 15, f"> {text} <") + painter.restore() + # Draw all solver points if self.sketch.entity_len(): painter.setPen(pen_solver) @@ -936,6 +1008,9 @@ class Line2D: # Construction Geometry self.is_helper: bool = False + # String list with applied constraints + self.constraints: list = [] + class Sketch2d(SolverSystem): """ diff --git a/requirements.txt b/requirements.txt index b6000b1..dfbcfbb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,66 +1,60 @@ -certifi==2024.7.4 -cffi==1.16.0 -charset-normalizer==3.3.2 -contourpy==1.2.0 +certifi==2025.1.31 +cffi==1.17.1 +charset-normalizer==3.4.1 +contourpy==1.3.1 cycler==0.12.1 -fonttools==4.47.0 -freetype-py==2.4.0 +flexcache==0.3 +flexparser==0.4 +fonttools==4.56.0 +freetype-py==2.5.1 hsluv==5.0.4 -idna==3.7 -imageio==2.33.1 -kiwisolver==1.4.5 -lazy_loader==0.3 +idna==3.10 +imageio==2.37.0 +kiwisolver==1.4.8 +lazy_loader==0.4 markdown-it-py==3.0.0 -matplotlib==3.8.2 +matplotlib==3.10.1 mdurl==0.1.2 -meshio==5.3.4 +meshio==5.3.5 names==0.3.0 -networkx==3.2.1 -Nuitka==2.2.1 -numpy==1.26.2 -numpy-stl==3.1.1 +networkx==3.4.2 +Nuitka==2.6.9 +numpy==2.2.4 +numpy-stl==3.2.0 ordered-set==4.1.0 -packaging==23.2 -panda3d-gltf==1.2.0 -panda3d-simplepbr==0.12.0 -Pillow==10.1.0 -Pint==0.22 -platformdirs==4.2.2 +packaging==24.2 +panda3d-gltf==1.3.0 +panda3d-simplepbr==0.13.0 +pillow==11.1.0 +Pint==0.24.4 +platformdirs==4.3.7 pooch==1.8.2 -pycparser==2.21 -pygame==2.5.2 -Pygments==2.17.2 -PyOpenGL==3.1.7 -pyparsing==3.1.1 -PyQt6==6.7.0 -PyQt6-3D==6.7.0 -PyQt6-3D-Qt6==6.7.0 -PyQt6-Qt6==6.7.0 -PyQt6-sip==13.6.0 -PySide6==6.6.1 -PySide6-Addons==6.6.1 -PySide6-Essentials==6.6.1 -python-dateutil==2.8.2 +pycparser==2.22 +pygame==2.6.1 +Pygments==2.19.1 +pyparsing==3.2.3 +PySide6_Essentials==6.8.3 +python-dateutil==2.9.0.post0 python-solvespace==3.0.8 -python-utils==3.8.2 -pyvista==0.43.10 -pyvistaqt==0.11.1 -QtPy==2.4.1 +python-utils==3.9.1 +pyvista==0.44.2 +pyvistaqt==0.11.2 +QtPy==2.4.3 requests==2.32.3 -rich==13.7.0 -scikit-image==0.22.0 -scipy==1.11.4 +rich==13.9.4 +scikit-image==0.25.2 +scipy==1.15.2 scooby==0.10.0 sdfcad @ git+https://gitlab.com/nobodyinperson/sdfCAD@9bd4e9021c6ee7e685ee28e8a3a5d2d2c028190c -shapely==2.0.4 -shiboken6==6.6.1 -six==1.16.0 -tifffile==2023.12.9 -trimesh==4.3.2 +shapely==2.1.0rc1 +shiboken6==6.8.3 +six==1.17.0 +tifffile==2025.3.13 +trimesh==4.6.5 tripy==1.0.0 -typing_extensions==4.9.0 -urllib3==2.2.2 -vispy==0.14.2 -vtk==9.3.0 -vulkan==1.3.275.0 -zstandard==0.22.0 +typing_extensions==4.13.0 +urllib3==2.3.0 +vispy==0.14.3 +vtk==9.4.1 +vulkan==1.3.275.1 +zstandard==0.23.0