From 842799b35fcd0d3c7766a5af7cc12f66c3c86f7f Mon Sep 17 00:00:00 2001 From: bklronin Date: Mon, 30 Dec 2024 13:54:15 +0100 Subject: [PATCH] - Sketch projection partly works again :) --- doc/flow.md | 16 +- drawing_modules/draw_widget_solve.py | 353 +++++++++++---------------- main.py | 69 ++++-- 3 files changed, 199 insertions(+), 239 deletions(-) diff --git a/doc/flow.md b/doc/flow.md index 9d8e3d1..b7b9690 100644 --- a/doc/flow.md +++ b/doc/flow.md @@ -18,4 +18,18 @@ - Project cartesian flattened mesh into 2D - Transform to 2D xy - Transform to linear space for 2D widget to draw. -- Result into 2D cartesian for body interaction extrude etc \ No newline at end of file +- Result into 2D cartesian for body interaction extrude etc + +### Elements + +So far these are the elements: + +- Project: Main File +- Timeline : Used to track the steps +- Assembly: Uses Components and Connectors to from Assemblies +- Component: Container for multiple smaller elements "part" +- Connector: Preserves connections between parts even if the part in between is deleted +- Code: A special type that directly builds bodys from sdfCAD code. +- Body: The 3D meshed result from sdfCAD +- Sketch: The base to draw new entities. +- Interactor: A special component mesh that is used to manipulate the bodys in 3d view. \ No newline at end of file diff --git a/drawing_modules/draw_widget_solve.py b/drawing_modules/draw_widget_solve.py index 8e060d8..2b8cbcb 100644 --- a/drawing_modules/draw_widget_solve.py +++ b/drawing_modules/draw_widget_solve.py @@ -1,7 +1,7 @@ import math import re from copy import copy -from typing import Optional +import uuid import numpy as np from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QInputDialog @@ -32,6 +32,11 @@ class SketchWidget(QWidget): self.sketch = Sketch2d() + def create_sketch(self, sketch_in ): + self.sketch = Sketch2d() + self.sketch.id = sketch_in.id + self.sketch.origin = sketch_in.origin + def get_sketch(self): return self.sketch @@ -45,28 +50,38 @@ class SketchWidget(QWidget): #self.update() def create_workplane(self): - self.sketch.working_plane = self.solv.create_2d_base() + self.sketch.wp = self.sketch.create_2d_base() def create_workplane_projected(self): - self.sketch.working_plane = self.solv.create_2d_base() + self.sketch.wp = self.sketch.create_2d_base() - def convert_proj_points(self): + def convert_proj_points(self, proj_points: list): + ### This needs to create a proper Point2D class with bool construction enbaled out_points = [] - for point in self.sketch.proj_points: - x, y = point - coord = QPoint(x, y) - out_points.append(coord) + for point in proj_points: + pnt = Point2D(point[0], point[1]) + # Construction + pnt.is_helper = True + print(point) + self.sketch.add_point(pnt) - self.sketch.proj_points = out_points - - def convert_proj_lines(self): + def convert_proj_lines(self, proj_lines: list): + ### same as for point out_lines = [] - for line in self.sketch.proj_lines: - start = QPoint(line[0][0], line[0][1]) - end = QPoint(line[1][0], line[1][1]) - coord = QLine(start, end) - out_lines.append(coord) - self.sketch.proj_lines = out_lines + for line in proj_lines: + start = Point2D(line[0][0], line[0][1]) + end = Point2D(line[1][0], line[1][1]) + start.is_helper = True + end.is_helper = True + + self.sketch.add_point(start) + self.sketch.add_point(end) + + lne = Line2D(start, end) + + #Construction + lne.is_helper = True + self.sketch.add_line(lne) def find_duplicate_points_2d(self, edges): points = [] @@ -114,9 +129,9 @@ class SketchWidget(QWidget): origin_handle = self.get_handle_from_ui_point(origin) qw, qx, qy, qz = self.normal_to_quaternion(normal) - slv_normal = self.solv.add_normal_3d(qw, qx, qy, qz) - self.sketch.working_plane = self.solv.add_work_plane(origin_handle, slv_normal) - print(self.sketch.working_plane) + slv_normal = self.sketch.add_normal_3d(qw, qx, qy, qz) + self.sketch.wp = self.sketch.add_work_plane(origin_handle, slv_normal) + print(self.sketch.wp) def get_handle_nr(self, input_str: str) -> int: # Define the regex pattern to extract the handle number @@ -160,16 +175,16 @@ class SketchWidget(QWidget): def get_line_handle_from_ui_point(self, ui_point: QPoint): """Input Qpoint that is on a line and you shall receive the handle of the line!""" for target_line_con in self.sketch.lines: - if self.is_point_on_line(ui_point, target_line_con['ui_points'][0], target_line_con['ui_points'][1]): - slv_handle = target_line_con['solv_handle'] + if self.is_point_on_line(ui_point, target_line_con.crd1.ui_point, target_line_con.crd2.ui_point): + slv_handle = target_line_con.handle return slv_handle def get_point_line_handles_from_ui_point(self, ui_point: QPoint) -> tuple: """Input Qpoint that is on a line and you shall receive the handles of the points of the line!""" for target_line_con in self.sketch.slv_lines: - if self.is_point_on_line(ui_point, target_line_con['ui_points'][0], target_line_con['ui_points'][1]): - lines_to_cons = target_line_con['solv_entity_points'] + if self.is_point_on_line(ui_point, target_line_con.crd1.ui_point, target_line_con.crd2.ui_point): + lines_to_cons = target_line_con.crd1.handle, target_line_con.crd2.handle return lines_to_cons @@ -210,18 +225,22 @@ class SketchWidget(QWidget): def viewport_to_local_coord(self, qt_pos : QPoint) -> QPoint: return QPoint(self.to_quadrant_coords(qt_pos)) - def check_all_points(self,) -> list: + def check_all_points(self) -> list: + """ + 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 i in range(self.solv.entity_len()): + for i in range(self.sketch.entity_len()): # 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) + entity = self.sketch.entity(i) + if entity.is_point_2d() and self.sketch.params(entity.params): + x_tbu, y_tbu = self.sketch.params(entity.params) point_solved = QPoint(x_tbu, y_tbu) new_points_ui.append(point_solved) @@ -248,7 +267,7 @@ class SketchWidget(QWidget): index, old_point, new_point = tbu_points_idx # Update the point in slv_points_main - self.sketch.points[index].point = new_point + self.sketch.points[index].ui_point = new_point # Print updated state # print("Updated slv_points_main:", self.slv_points_main) @@ -256,10 +275,10 @@ class SketchWidget(QWidget): for tbu_points_idx in changed_points: index, old_point, new_point = tbu_points_idx for line_needs_update in self.sketch.lines: - if old_point == line_needs_update.points[0]: - line_needs_update['ui_points'][0] = new_point - elif old_point == line_needs_update.points[1]: - line_needs_update['ui_points'][1] = new_point + if old_point == line_needs_update.crd1.ui_point: + line_needs_update.crd1.ui_point = new_point + elif old_point == line_needs_update.crd2.ui_point: + line_needs_update.crd2.ui_point = new_point def mouseReleaseEvent(self, event): local_event_pos = self.viewport_to_local_coord(event.pos()) @@ -345,19 +364,20 @@ class SketchWidget(QWidget): if self.main_buffer[0] and self.main_buffer[1]: print("buf", self.main_buffer) - self.solv.coincident(self.main_buffer[0], self.main_buffer[1], self.sketch.working_plane) + self.sketch.coincident(self.main_buffer[0], self.main_buffer[1], self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") + self.constrain_done.emit() self.main_buffer = [None, None] @@ -373,19 +393,19 @@ class SketchWidget(QWidget): # Contrain point to line if self.main_buffer[1]: - self.solv.coincident(self.main_buffer[0], self.main_buffer[1], self.sketch.working_plane) + self.sketch.coincident(self.main_buffer[0], self.main_buffer[1], self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") self.constrain_done.emit() - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") self.constrain_done.emit() @@ -404,18 +424,18 @@ class SketchWidget(QWidget): # Contrain point to line if self.main_buffer[1]: - self.solv.midpoint(self.main_buffer[0], self.main_buffer[1], self.sketch.working_plane) + self.sketch.midpoint(self.main_buffer[0], self.main_buffer[1], self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") self.constrain_done.emit() @@ -426,36 +446,36 @@ class SketchWidget(QWidget): line_selected = self.get_line_handle_from_ui_point(local_event_pos) if line_selected: - self.solv.horizontal(line_selected, self.sketch.working_plane) + self.sketch.horizontal(line_selected, self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") 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.solv.vertical(line_selected, self.sketch.working_plane) + self.sketch.vertical(line_selected, self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") if event.button() == Qt.LeftButton and self.mouse_mode == "distance": @@ -485,18 +505,18 @@ class SketchWidget(QWidget): if e1 and e2: # Ask fo the dimension and solve if both elements are present length, ok = QInputDialog.getDouble(self, 'Distance', 'Enter a mm value:', value=100, decimals=2) - self.solv.distance(e1, e2, length, self.sketch.working_plane) + self.sketch.distance(e1, e2, length, self.sketch.wp) - if self.solv.solve() == ResultFlag.OKAY: + if self.sketch.solve() == ResultFlag.OKAY: print("Fuck yeah") - elif self.solv.solve() == ResultFlag.DIDNT_CONVERGE: + elif self.sketch.solve() == ResultFlag.DIDNT_CONVERGE: print("Solve_failed - Converge") - elif self.solv.solve() == ResultFlag.TOO_MANY_UNKNOWNS: + elif self.sketch.solve() == ResultFlag.TOO_MANY_UNKNOWNS: print("Solve_failed - Unknowns") - elif self.solv.solve() == ResultFlag.INCONSISTENT: + elif self.sketch.solve() == ResultFlag.INCONSISTENT: print("Solve_failed - Incons") self.constrain_done.emit() @@ -661,33 +681,53 @@ class SketchWidget(QWidget): # Set the transform to the painter painter.setTransform(transform) - pen = QPen(Qt.gray) - pen.setWidthF(2 / self.zoom) - painter.setPen(pen) + pen_normal = QPen(Qt.gray) + pen_normal.setWidthF(2 / self.zoom) + + pen_construct = QPen(Qt.blue) + pen_construct.setStyle(Qt.PenStyle.DashLine) + pen_construct.setWidthF(2 / self.zoom) + + pen_solver = QPen(Qt.green) + pen_solver.setWidthF(2 / self.zoom) # Draw points if self.sketch: + painter.setPen(pen_normal) for point in self.sketch.points: - painter.drawEllipse(point.ui_point, 3 / self.zoom, 3 / self.zoom) + if point.is_helper: + painter.setPen(pen_construct) + painter.drawEllipse(point.ui_point, 10 / self.zoom, 10 / self.zoom) + else: + #Normal point + painter.setPen(pen_normal) + painter.drawEllipse(point.ui_point, 3 / self.zoom, 3 / self.zoom) + for line in self.sketch.lines: - p1 = line.crd1.ui_point - p2 = line.crd2.ui_point - painter.drawLine(p1, p2) + if line.is_helper: + painter.setPen(pen_construct) + p1 = line.crd1.ui_point + p2 = line.crd2.ui_point + painter.drawLine(p1, p2) + else: + painter.setPen(pen_normal) + p1 = line.crd1.ui_point + p2 = line.crd2.ui_point + painter.drawLine(p1, p2) - dis = self.distance(p1, p2) - mid = self.calculate_midpoint(p1, p2) - painter.drawText(mid, str(round(dis, 2))) + dis = self.distance(p1, p2) + mid = self.calculate_midpoint(p1, p2) + painter.drawText(mid, str(round(dis, 2))) - pen = QPen(Qt.green) - pen.setWidthF(2 / self.zoom) - painter.setPen(pen) - if self.solv.entity_len(): - for i in range(self.solv.entity_len()): - entity = self.solv.entity(i) - if entity.is_point_2d() and self.solv.params(entity.params): - x, y = self.solv.params(entity.params) + # Draw all solver points + if self.sketch.entity_len(): + painter.setPen(pen_solver) + for i in range(self.sketch.entity_len()): + entity = self.sketch.entity(i) + if entity.is_point_2d() and self.sketch.params(entity.params): + x, y = self.sketch.params(entity.params) point = QPointF(x, y) painter.drawEllipse(point, 6 / self.zoom, 6 / self.zoom) @@ -723,149 +763,30 @@ class SketchWidget(QWidget): return self.width() / self.height() * (1.0 / abs(self.zoom)) -class Point2D_ALT: - """Improved oop aaproach?""" - def __init__(self): - self.ui_point = None - self.solve_handle_nr = None - self.solve_handle = None - self.part_of_entity = None - - 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 = center_y - point.y() # Note the change here - - return QPoint(quadrant_x, quadrant_y) / self.zoom - - def from_quadrant_coords(self, point: QPoint): - """Translate quadrant coordinates to linear coordinates.""" - center_x = self.width() // 2 - center_y = self.height() // 2 - widget_x = center_x + point.x() * self.zoom - widget_y = center_y - point.y() * self.zoom # Note the subtraction here - - return QPoint(int(widget_x), int(widget_y)) - - def from_quadrant_coords_no_center(self, point): - """Invert Y Coordinate for mesh""" - center_x = 0 - center_y = 0 - widget_x = point.x() - widget_y = -point.y() - - return QPoint(int(widget_x), int(widget_y)) - - def get_handle_nr(self, input_str: str) -> int: - # Define the regex pattern to extract the handle number - pattern = r"handle=(\d+)" - - # Use re.search to find the handle number in the string - match = re.search(pattern, input_str) - - 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: - result = [] - path = [] - print(d) - print(target) - for k, v in d.items(): - path.append(k) - if isinstance(v, dict): - self.get_keys(v, target) - if v == target: - result.append(copy(path)) - path.pop() - - return result - - def get_handle_from_ui_point(self, ui_point: QPoint): - """Input QPoint and you shall reveive a slvs entity handle!""" - for point in self.sketch.slv_points: - if ui_point == point['ui_point']: - slv_handle = point['solv_handle'] - - return slv_handle - - def get_line_handle_from_ui_point(self, ui_point: QPoint): - """Input Qpoint that is on a line and you shall receive the handle of the line!""" - for target_line_con in self.sketch.slv_lines: - if self.is_point_on_line(ui_point, target_line_con['ui_points'][0], target_line_con['ui_points'][1]): - slv_handle = target_line_con['solv_handle'] - - return slv_handle - - def get_point_line_handles_from_ui_point(self, ui_point: QPoint) -> tuple: - """Input Qpoint that is on a line and you shall receive the handles of the points of the line!""" - for target_line_con in self.sketch.slv_lines: - if self.is_point_on_line(ui_point, target_line_con['ui_points'][0], target_line_con['ui_points'][1]): - lines_to_cons = target_line_con['solv_entity_points'] - - return lines_to_cons - - def distance(self, p1, p2): - return math.sqrt((p1.x() - p2.x())**2 + (p1.y() - p2.y())**2) - - def calculate_midpoint(self, point1, point2): - mx = (point1.x() + point2.x()) // 2 - my = (point1.y() + point2.y()) // 2 - return QPoint(mx, my) - - 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: - return QPoint(self.to_quadrant_coords(qt_pos)) - - - +### GEOMETRY CLASSES class Point2D: def __init__(self, x, y): + self.id = None self.ui_x: int = x self.ui_y: int = y self.ui_point = QPoint(self.ui_x, self.ui_y) self.handle = None self.handle_nr: int = None + # Construction Geometry + self.is_helper: bool = False + class Line2D: def __init__(self, point_s: Point2D, point_e: Point2D): + self.id = None + self.crd1: Point2D = point_s self.crd2: Point2D = point_e self.handle = None - self.handle_nr = None + self.handle_nr: int = None + + # Construction Geometry + self.is_helper: bool = False class Sketch2d(SolverSystem): """ @@ -873,13 +794,16 @@ class Sketch2d(SolverSystem): """ def __init__(self): + self.id = uuid.uuid1() + self.wp = self.create_2d_base() self.points = [] self.lines = [] + self.origin = [0,0,0] def add_point(self, point: Point2D): """ - Adds a point into the solversystem and reurns the handle. + Adds a point into the solversystem and returns the handle. Appends the added point to the points list. :param point: 2D point in Point2D class format :return: @@ -887,6 +811,7 @@ class Sketch2d(SolverSystem): point.handle = self.add_point_2d(point.ui_x, point.ui_y, self.wp) point.handle_nr = self.get_handle_nr(str(point.handle)) + point.id = uuid.uuid1() self.points.append(point) @@ -899,6 +824,8 @@ class Sketch2d(SolverSystem): :return: """ + line.id = uuid.uuid1() + line.handle = self.add_line_2d(line.crd1.handle, line.crd2.handle, self.wp) line.handle_nr = self.get_handle_nr(str(line.handle)) diff --git a/main.py b/main.py index aa12c1f..b5e25da 100644 --- a/main.py +++ b/main.py @@ -49,7 +49,6 @@ class ExtrudeDialog(QDialog): self.rounded_checkbox = QCheckBox('Round Edges') self.seperator = create_hline() - # OK and Cancel buttons button_layout = QHBoxLayout() ok_button = QPushButton('OK') @@ -263,14 +262,12 @@ class MainWindow(QMainWindow): sketch = Sketch() sketch.id = name sketch.origin = [0,0,0] - sketch.slv_points = [] - sketch.slv_lines = [] - sketch.proj_points = [] - sketch.proj_lines = [] + self.sketchWidget.reset_buffers() - self.sketchWidget.set_sketch(sketch) + self.sketchWidget.create_sketch(sketch) def add_new_sketch_wp(self): + ## Sketch projected from 3d view into 2d name = f"sketches-{str(names.get_first_name())}" sketch = Sketch() sketch.id = name @@ -280,11 +277,13 @@ class MainWindow(QMainWindow): sketch.slv_lines = [] sketch.proj_points = self.custom_3D_Widget.project_tosketch_points sketch.proj_lines = self.custom_3D_Widget.project_tosketch_lines + self.sketchWidget.reset_buffers() - self.sketchWidget.set_sketch(sketch) + self.sketchWidget.create_sketch(sketch) self.sketchWidget.create_workplane_projected() - self.sketchWidget.convert_proj_points() - self.sketchWidget.convert_proj_lines() + if not sketch.proj_lines: + self.sketchWidget.convert_proj_points(sketch.proj_points) + self.sketchWidget.convert_proj_lines(sketch.proj_lines) self.sketchWidget.update() # CLear all selections after it has been projected @@ -295,15 +294,24 @@ class MainWindow(QMainWindow): def add_sketch(self): """ - :return: """ - sketch = self.sketchWidget.get_sketch() - sketch.convert_points_for_sdf() + sketch = Sketch() + sketch_from_widget = self.sketchWidget.get_sketch() + points = sketch_from_widget.points + sketch.convert_points_for_sdf(points) + sketch.id = sketch_from_widget.id + + sketch.filter_lines_for_interactor(sketch_from_widget.lines) + + # Register sketch to timeline self.project.timeline[-1].sketches[sketch.id] = sketch + # Add Item to slection menu self.ui.sketch_list.addItem(sketch.id) + + # Deactivate drawing self.ui.pb_linetool.setChecked(False) self.sketchWidget.line_mode = False @@ -387,7 +395,9 @@ class MainWindow(QMainWindow): name = selected.text() # TODO: add selected element from timeline sel_compo = self.project.timeline[-1] + print(sel_compo) sketch = sel_compo.sketches[name] + print(sketch) points = sketch.sdf_points if points[-1] == points[0]: @@ -428,7 +438,7 @@ class MainWindow(QMainWindow): ### Interactor interactor = Interactor() - interactor.add_lines_for_interactor(sketch.slv_lines) + interactor.add_lines_for_interactor(sketch.interactor_lines) if not invert: edges = interactor_mesh.generate_mesh(interactor.lines, 0, length) @@ -564,6 +574,8 @@ class Sketch: sdf_points: list = None + interactor_lines: list = None + # Points coming back from the 3D-Widget as projection to draw on proj_points: list = None proj_lines: list = None @@ -623,13 +635,24 @@ class Sketch: print("p2", p2) return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) - def convert_points_for_sdf(self): + def convert_points_for_sdf(self, points): points_for_sdf = [] - for point_to_poly in self.slv_points: - points_for_sdf.append(self.translate_points_tup(point_to_poly['ui_point'])) + for point in points: + if point.is_helper is False: + print("point", point) + points_for_sdf.append(self.translate_points_tup(point.ui_point)) self.sdf_points = points_for_sdf + def filter_lines_for_interactor(self, lines): + ### Filter lines that are not meant to be drawn for the interactor like contruction lines + filtered_lines = [] + for line in lines: + if not line.is_helper: + filtered_lines.append(line) + + self.interactor_lines = filtered_lines + def extrude(self, height: float, symet: bool = True, invert: bool = False, offset_length: float = None): """ Extrude a 2D shape into 3D, orient it along the normal, and position it relative to the centroid. @@ -677,7 +700,6 @@ class Sketch: return f - @dataclass class Interactor: """Helper mesh consisting of edges for selection""" @@ -708,12 +730,13 @@ class Interactor: return translation_along_normal def add_lines_for_interactor(self, input_lines: list): - """Expects slvs_lines main list""" + """Takes Line2D objects from the sketch widget and preparesit for interactor mesh. + Translates coordinates.""" + points_for_interact = [] for point_to_poly in input_lines: - start, end = point_to_poly['ui_points'] - from_coord_start = window.sketchWidget.from_quadrant_coords_no_center(start) - from_coord_end = window.sketchWidget.from_quadrant_coords_no_center(end) + from_coord_start = window.sketchWidget.from_quadrant_coords_no_center(point_to_poly.crd1.ui_point) + from_coord_end = window.sketchWidget.from_quadrant_coords_no_center(point_to_poly.crd2.ui_point) start_draw = self.translate_points_tup(from_coord_start) end_draw = self.translate_points_tup(from_coord_end) line = start_draw, end_draw @@ -723,7 +746,6 @@ class Interactor: self.lines = points_for_interact - @dataclass class Body: """The actual body as sdf3 object""" @@ -743,7 +765,6 @@ class Body: return f - class Output: def export_mesh(self, sdf_object): """FINAL EXPORT""" @@ -763,13 +784,11 @@ class Output: except Exception as e: print("Error executing code:", e) - class Project: """Project -> Timeline -> Component -> Sketch -> Body / Interactor -> Connector -> Assembly -> PB Render""" timeline: Timeline = None assembly: Assembly = None - if __name__ == "__main__": app = QApplication([]) window = MainWindow()