- Bsic sketch to object approach
This commit is contained in:
parent
b80185e93e
commit
511b5da78a
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
3
main.py
3
main.py
@ -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()
|
||||||
|
BIN
modules/out.stl
BIN
modules/out.stl
Binary file not shown.
@ -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
|
Loading…
x
Reference in New Issue
Block a user