- Bsic sketch to object approach

This commit is contained in:
bklronin 2024-08-16 20:21:21 +02:00
parent b80185e93e
commit 511b5da78a
5 changed files with 162 additions and 12 deletions

View File

@ -356,8 +356,11 @@ class SketchWidget(QWidget):
print("Buffer state", self.line_draw_buffer) print("Buffer state", self.line_draw_buffer)
if self.line_draw_buffer[0] and self.line_draw_buffer[1]: if self.line_draw_buffer[0] and self.line_draw_buffer[1]:
point_slv1 = self.get_handle_from_ui_point(self.line_draw_buffer[0]) point_slv1 = self.get_handle_from_ui_point(self.line_draw_buffer[0])
point_slv2 = self.get_handle_from_ui_point(self.line_draw_buffer[1]) point_slv2 = self.get_handle_from_ui_point(self.line_draw_buffer[1])
print(point_slv1)
print(point_slv2)
line = self.solv.add_line_2d(point_slv1, point_slv2, self.sketch.working_plane) line = self.solv.add_line_2d(point_slv1, point_slv2, self.sketch.working_plane)
@ -768,7 +771,139 @@ class SketchWidget(QWidget):
return self.width() / self.height() * (1.0 / abs(self.zoom)) return self.width() / self.height() * (1.0 / abs(self.zoom))
# Example usage class Point2D:
"""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))
class Line2D:
pass
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys

View File

@ -1,25 +1,35 @@
from python_solvespace import SolverSystem, ResultFlag from python_solvespace import SolverSystem, ResultFlag
def solve_constraint(self): def solve_constraint():
solv = SolverSystem() solv = SolverSystem()
wp = solv.create_2d_base() # Workplane (Entity) wp = solv.create_2d_base() # Workplane (Entity)
p0 = solv.add_point_2d(0, 0, wp) # Entity p0 = solv.add_point_2d(0, 0, wp) # Entity
p1 = solv.add_point_2d(10, 10, wp) # Entity
p2 = solv.add_point_2d(0, 10, wp) # Entity
solv.dragged(p0, wp) # Make a constraint with the entity solv.dragged(p0, wp) # Make a constraint with the entity
...
line0 = solv.add_line_2d(p0, p1, wp) # Create entity with others line0 = solv.add_line_2d(p0, p1, wp) # Create entity with others
... line1 = solv.add_line_2d(p0, p2, wp)
line1 = solv.add_line_2d(p0, p3, wp) #solv.angle(line0, line1, 45, wp) # Constrain two entities
solv.angle(line0, line1, 45, wp) # Constrain two entities solv.coincident(p0, p1, wp)
solv.add_constraint(100006, wp, 0, p1,p2, line0, line1)
line1 = solv.entity(-1) # Entity handle can be re-generated and negatively indexed line1 = solv.entity(-1) # Entity handle can be re-generated and negatively indexed
... solv.
if solv.solve() == ResultFlag.OKAY: if solv.solve() == ResultFlag.OKAY:
# Get the result (unpack from the entity or parameters) # Get the result (unpack from the entity or parameters)
# x and y are actually float type # x and y are actually float type
dof = solv.dof() dof = solv.dof()
x, y = solv.params(p2.params) x, y = solv.params(p1.params)
... print(dof)
print(x)
print(y)
else: else:
# Error! # Error!
# Get the list of all constraints # Get the list of all constraints
failures = solv.failures() failures = solv.failures()
... print(failures)
...
solve_constraint()

View File

@ -267,6 +267,7 @@ class MainWindow(QMainWindow):
sketch.slv_lines = [] sketch.slv_lines = []
sketch.proj_points = [] sketch.proj_points = []
sketch.proj_lines = [] sketch.proj_lines = []
self.sketchWidget.reset_buffers()
self.sketchWidget.set_sketch(sketch) self.sketchWidget.set_sketch(sketch)
def add_new_sketch_wp(self): def add_new_sketch_wp(self):
@ -279,6 +280,7 @@ class MainWindow(QMainWindow):
sketch.slv_lines = [] sketch.slv_lines = []
sketch.proj_points = self.custom_3D_Widget.project_tosketch_points sketch.proj_points = self.custom_3D_Widget.project_tosketch_points
sketch.proj_lines = self.custom_3D_Widget.project_tosketch_lines sketch.proj_lines = self.custom_3D_Widget.project_tosketch_lines
self.sketchWidget.reset_buffers()
self.sketchWidget.set_sketch(sketch) self.sketchWidget.set_sketch(sketch)
self.sketchWidget.create_workplane_projected() self.sketchWidget.create_workplane_projected()
self.sketchWidget.convert_proj_points() self.sketchWidget.convert_proj_points()
@ -765,7 +767,6 @@ class Project:
assembly: Assembly = None assembly: Assembly = None
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication([]) app = QApplication([])
window = MainWindow() window = MainWindow()

Binary file not shown.

View File

@ -2,9 +2,13 @@ matplotlib==3.8.2
numpy==1.26.2 numpy==1.26.2
Pillow==10.1.0 Pillow==10.1.0
Pint==0.22 Pint==0.22
pygame==2.5.2
PySide6==6.6.1 PySide6==6.6.1
rich==13.7.0 rich==13.7.0
scikit-image==0.22.0 scikit-image==0.22.0
scipy==1.11.4 scipy==1.11.4
vtk==9.3.0 vtk==9.3.0
names~=0.3.0
shapely~=2.0.4
pyvista~=0.43.10
pyvistaqt~=0.11.1