- delete sketch working

- added mid point snap
- added hovering line with distance
This commit is contained in:
bklronin 2025-01-01 21:35:43 +01:00
parent f5861b8bd1
commit e9383f76a2
2 changed files with 75 additions and 50 deletions

View File

@ -19,6 +19,7 @@ class SketchWidget(QWidget):
self.line_draw_buffer = [None, None] self.line_draw_buffer = [None, None]
self.drag_buffer = [None, None] self.drag_buffer = [None, None]
self.main_buffer = [None, None] self.main_buffer = [None, None]
self.dynamic_line_end = None # Cursor position for dynamic drawing
self.hovered_point = None self.hovered_point = None
self.selected_line = None self.selected_line = None
@ -186,7 +187,7 @@ class SketchWidget(QWidget):
def get_point_line_handles_from_ui_point(self, ui_point: QPoint) -> tuple: 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!""" """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: for target_line_con in self.sketch.lines:
if self.is_point_on_line(ui_point, target_line_con.crd1.ui_point, target_line_con.crd2.ui_point): 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 lines_to_cons = target_line_con.crd1.handle, target_line_con.crd2.handle
@ -535,13 +536,18 @@ class SketchWidget(QWidget):
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
local_event_pos = self.viewport_to_local_coord(event.pos()) local_event_pos = self.viewport_to_local_coord(event.pos())
#print(local_event_pos)
closest_point = None closest_point = None
min_distance = float('inf') min_distance = float('inf')
threshold = 10 # Distance threshold for highlighting threshold = 10 # Distance threshold for highlighting
if len(self.sketch.points) > 0: if self.mouse_mode == "line" and self.line_draw_buffer[0]:
# Update the current cursor position as the second point
self.dynamic_line_end = self.viewport_to_local_coord(event.pos())
self.update() # Trigger a repaint
if self.sketch.points is not None and len(self.sketch.points) > 0:
for point in self.sketch.points: for point in self.sketch.points:
distance = (local_event_pos - point.ui_point).manhattanLength() distance = (local_event_pos - point.ui_point).manhattanLength()
if distance < threshold and distance < min_distance: if distance < threshold and distance < min_distance:
@ -564,6 +570,10 @@ class SketchWidget(QWidget):
if self.is_point_on_line(local_event_pos, p1, p2): if self.is_point_on_line(local_event_pos, p1, p2):
self.selected_line = p1, p2 self.selected_line = p1, p2
mid = self.calculate_midpoint(p1, p2)
distance = (local_event_pos - mid).manhattanLength()
if distance < threshold and distance < min_distance:
self.hovered_point = mid
break break
else: else:
self.selected_line = None self.selected_line = None
@ -695,7 +705,10 @@ class SketchWidget(QWidget):
pen_solver = QPen(Qt.green) pen_solver = QPen(Qt.green)
pen_solver.setWidthF(2 / self.zoom) pen_solver.setWidthF(2 / self.zoom)
# Draw points pen_text = QPen(Qt.white)
pen_text.setWidthF(1 / self.zoom)
# Draw points and lines
if self.sketch: if self.sketch:
painter.setPen(pen_normal) painter.setPen(pen_normal)
for point in self.sketch.points: for point in self.sketch.points:
@ -703,10 +716,34 @@ class SketchWidget(QWidget):
painter.setPen(pen_construct) painter.setPen(pen_construct)
painter.drawEllipse(point.ui_point, 10 / self.zoom, 10 / self.zoom) painter.drawEllipse(point.ui_point, 10 / self.zoom, 10 / self.zoom)
else: else:
#Normal point # Normal point
painter.setPen(pen_normal) painter.setPen(pen_normal)
painter.drawEllipse(point.ui_point, 3 / self.zoom, 3 / self.zoom) painter.drawEllipse(point.ui_point, 3 / self.zoom, 3 / self.zoom)
# Draw the dynamic line
if self.mouse_mode == "line" and self.line_draw_buffer[0] and self.dynamic_line_end is not None:
start_point = self.line_draw_buffer[0].ui_point
end_point = self.dynamic_line_end
painter.setPen(Qt.red) # Use a different color for the dynamic line
painter.drawLine(start_point, end_point)
# 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(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()
for line in self.sketch.lines: for line in self.sketch.lines:
if line.is_helper: if line.is_helper:
@ -720,11 +757,6 @@ class SketchWidget(QWidget):
p2 = line.crd2.ui_point p2 = line.crd2.ui_point
painter.drawLine(p1, p2) painter.drawLine(p1, p2)
dis = self.distance(p1, p2)
mid = self.calculate_midpoint(p1, p2)
painter.drawText(mid, str(round(dis, 2)))
# Draw all solver points # Draw all solver points
if self.sketch.entity_len(): if self.sketch.entity_len():
painter.setPen(pen_solver) painter.setPen(pen_solver)

75
main.py
View File

@ -6,7 +6,7 @@
import uuid import uuid
import names import names
from PySide6.QtCore import Qt, QPoint, Signal, QSize from PySide6.QtCore import Qt, QPoint, Signal, QSize
from PySide6.QtWidgets import QApplication, QMainWindow, QSizePolicy, QInputDialog, QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QCheckBox, QPushButton from PySide6.QtWidgets import QApplication, QMainWindow, QSizePolicy, QInputDialog, QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QCheckBox, QPushButton, QButtonGroup
from Gui import Ui_fluencyCAD # Import the generated GUI module from Gui import Ui_fluencyCAD # Import the generated GUI module
from drawing_modules.vtk_widget import VTKWidget from drawing_modules.vtk_widget import VTKWidget
from drawing_modules.vysta_widget import PyVistaWidget from drawing_modules.vysta_widget import PyVistaWidget
@ -156,6 +156,7 @@ class MainWindow(QMainWindow):
self.project.timeline = timeline self.project.timeline = timeline
self.new_component() self.new_component()
def new_component(self): def new_component(self):
print("Creating a new component...") print("Creating a new component...")
@ -164,6 +165,10 @@ class MainWindow(QMainWindow):
print("Initializing compo_layout...") print("Initializing compo_layout...")
self.compo_layout = QHBoxLayout() self.compo_layout = QHBoxLayout()
# Create a button group
self.compo_group = QButtonGroup(self)
self.compo_group.setExclusive(True) # Ensure exclusivity
# Ensure the QGroupBox has a layout # Ensure the QGroupBox has a layout
if not self.ui.compo_box.layout(): if not self.ui.compo_box.layout():
self.ui.compo_box.setLayout(QVBoxLayout()) # Set a default layout for QGroupBox self.ui.compo_box.setLayout(QVBoxLayout()) # Set a default layout for QGroupBox
@ -188,13 +193,19 @@ class MainWindow(QMainWindow):
button.setText(str(len(self.project.timeline))) button.setText(str(len(self.project.timeline)))
button.setFixedSize(QSize(40, 40)) # Set button size button.setFixedSize(QSize(40, 40)) # Set button size
button.setCheckable(True) button.setCheckable(True)
button.setAutoExclusive(True) #button.setAutoExclusive(True)
button.setChecked(False)
button.released.connect(self.on_compo_change) button.released.connect(self.on_compo_change)
button.setChecked(True)
# Add button to the group
self.compo_group.addButton(button)
# Add the button to the layout # Add the button to the layout
self.compo_layout.addWidget(button) self.compo_layout.addWidget(button)
# We automatically switch to the new compo hence, refresh
self.on_compo_change()
print(f"Added component {compo.id} to the layout.") print(f"Added component {compo.id} to the layout.")
def get_activated_compo(self): def get_activated_compo(self):
@ -285,6 +296,7 @@ class MainWindow(QMainWindow):
def on_compo_change(self): def on_compo_change(self):
self.custom_3D_Widget.clear_body_actors() self.custom_3D_Widget.clear_body_actors()
self.custom_3D_Widget.clear_actors_interactor() self.custom_3D_Widget.clear_actors_interactor()
self.custom_3D_Widget.clear_actors_projection()
compo_id = self.get_activated_compo() compo_id = self.get_activated_compo()
if compo_id is not None: if compo_id is not None:
@ -301,16 +313,17 @@ class MainWindow(QMainWindow):
for body in self.project.timeline[compo_id].bodies: for body in self.project.timeline[compo_id].bodies:
self.ui.body_list.addItem(body) self.ui.body_list.addItem(body)
item = self.ui.body_list.findItems(body , Qt.MatchExactly)[0] if self.project.timeline[compo_id].bodies:
self.ui.body_list.setCurrentItem(item) item = self.ui.body_list.findItems(body , Qt.MatchExactly)[0]
self.draw_mesh() self.ui.body_list.setCurrentItem(item)
self.draw_mesh()
selected = self.ui.body_list.currentItem() selected = self.ui.body_list.currentItem()
name = selected.text() name = selected.text()
edges = self.project.timeline[compo_id].bodies[name].interactor.edges edges = self.project.timeline[compo_id].bodies[name].interactor.edges
offset_vec = self.project.timeline[compo_id].bodies[name].interactor.offset_vector offset_vec = self.project.timeline[compo_id].bodies[name].interactor.offset_vector
self.custom_3D_Widget.load_interactor_mesh(edges, offset_vec) self.custom_3D_Widget.load_interactor_mesh(edges, offset_vec)
def edit_sketch(self): def edit_sketch(self):
selected = self.ui.sketch_list.currentItem() selected = self.ui.sketch_list.currentItem()
@ -323,40 +336,20 @@ class MainWindow(QMainWindow):
self.sketchWidget.update() self.sketchWidget.update()
def del_sketch(self): def del_sketch(self):
# Old selected = self.ui.sketch_list.currentItem()
print("Deleting") name = selected.text()
name = self.ui.sketch_list.currentItem() # Get the current item sel_compo = self.project.timeline[self.get_activated_compo()]
sketch = sel_compo.sketches[name]
print(self.model) if sketch is not None:
sel_compo.sketches.pop(name)
if name is not None: row = self.ui.sketch_list.row(selected) # Get the row of the current item
item_name = name.text() self.ui.sketch_list.takeItem(row) # Remove the item from the list widget
print("obj_name", item_name) self.sketchWidget.sketch = None
print(sketch)
# Check if the 'sketches' key exists in the model dictionary
if 'sketches' in self.model and item_name in self.model['sketches']:
if self.model['sketches'][item_name]['id'] == item_name:
row = self.ui.sketch_list.row(name) # Get the row of the current item
self.ui.sketch_list.takeItem(row) # Remove the item from the list widget
self.sketchWidget.clear_sketch()
self.model['sketches'].pop(item_name) # Remove the item from the sketches dictionary
print(f"Removed sketches: {item_name}")
# Check if the 'operation' key exists in the model dictionary
elif 'operation' in self.model and item_name in self.model['operation']:
if self.model['operation'][item_name]['id'] == item_name:
row = self.ui.sketch_list.row(name) # Get the row of the current item
self.ui.sketch_list.takeItem(row) # Remove the item from the list widget
self.sketchWidget.clear_sketch()
self.model['operation'].pop(item_name) # Remove the item from the operation dictionary
print(f"Removed operation: {item_name}")
else:
print(f"Item '{item_name}' not found in either 'sketches' or 'operation' dictionary.")
else: else:
print("No item selected.") print("No item selected.")
def on_flip_face(self): def on_flip_face(self):
self.send_command.emit("flip") self.send_command.emit("flip")