- Sketch projection and extrude in place working
This commit is contained in:
@@ -18,11 +18,13 @@ class SketchWidget(QWidget):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.line_draw_buffer = [None, None]
|
||||
self.drag_buffer = [None, None]
|
||||
self.main_buffer = [None, None]
|
||||
|
||||
self.proj_snap_points = []
|
||||
self.proj_snap_lines = []
|
||||
|
||||
self.hovered_point = None
|
||||
self.selected_line = None
|
||||
@@ -59,7 +61,9 @@ class SketchWidget(QWidget):
|
||||
for point in lines:
|
||||
print(point)
|
||||
x, y = point
|
||||
self.proj_snap_points = lines
|
||||
self.proj_snap_lines = lines
|
||||
self.proj_snap_points.append(QPoint(x, y))
|
||||
|
||||
|
||||
#point = self.solv.add_point_2d(x, y, self.wp)
|
||||
|
||||
@@ -311,7 +315,10 @@ class SketchWidget(QWidget):
|
||||
self.reset_buffers()
|
||||
|
||||
if event.button() == Qt.LeftButton and self.mouse_mode == "line":
|
||||
clicked_pos = local_event_pos
|
||||
if self.hovered_point:
|
||||
clicked_pos = self.hovered_point
|
||||
else:
|
||||
clicked_pos = local_event_pos
|
||||
|
||||
if not self.line_draw_buffer[0]:
|
||||
self.line_draw_buffer[0] = clicked_pos
|
||||
@@ -564,6 +571,12 @@ class SketchWidget(QWidget):
|
||||
closest_point = point['ui_point']
|
||||
min_distance = distance
|
||||
|
||||
for point in self.proj_snap_points:
|
||||
distance = (local_event_pos - point).manhattanLength()
|
||||
if distance < threshold and distance < min_distance:
|
||||
closest_point = point
|
||||
min_distance = distance
|
||||
|
||||
if closest_point != self.hovered_point:
|
||||
self.hovered_point = closest_point
|
||||
print(self.hovered_point)
|
||||
@@ -636,7 +649,7 @@ class SketchWidget(QWidget):
|
||||
|
||||
def draw_cross(self, painter, x, y, size=10):
|
||||
# Set up the pen
|
||||
pen = QPen(QColor('red')) # You can change the color as needed
|
||||
pen = QPen(QColor('green')) # You can change the color as needed
|
||||
pen.setWidth(int(2 / self.zoom)) # Set the line widt)h
|
||||
painter.setPen(pen)
|
||||
|
||||
@@ -712,7 +725,7 @@ class SketchWidget(QWidget):
|
||||
painter.setPen(QPen(Qt.red, 2))
|
||||
painter.drawLine(p1, p2)
|
||||
|
||||
for cross in self.proj_snap_points:
|
||||
for cross in self.proj_snap_lines:
|
||||
# Calculate the endpoints of the cross
|
||||
self.draw_cross(painter, cross[0], cross[1], 10)
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
self.vtk_widget = QVTKRenderWindowInteractor(self)
|
||||
|
||||
self.picked_edge_actors = []
|
||||
self.displayed_normal_actors = []
|
||||
|
||||
self.flip_toggle = False
|
||||
|
||||
# Create layout and add VTK widget
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
@@ -38,8 +41,26 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
# Set up the camera
|
||||
self.camera = self.renderer.GetActiveCamera()
|
||||
self.camera.SetPosition(5, 5, 100)
|
||||
self.camera.SetPosition(5, 5, 1000)
|
||||
self.camera.SetFocalPoint(0, 0, 0)
|
||||
self.camera.SetClippingRange(0.1, 10000)
|
||||
|
||||
# Light Setup
|
||||
def add_light(renderer, position, color=(1, 1, 1), intensity=1.0):
|
||||
light = vtk.vtkLight()
|
||||
light.SetPosition(position)
|
||||
light.SetColor(color)
|
||||
light.SetIntensity(intensity)
|
||||
renderer.AddLight(light)
|
||||
|
||||
# Add lights from multiple directions
|
||||
add_light(self.renderer, (1000, 0, 0), intensity=1.5)
|
||||
add_light(self.renderer, (-1000, 0, 0), intensity=1.5)
|
||||
add_light(self.renderer, (0, 1000, 0), intensity=1.5)
|
||||
add_light(self.renderer, (0, -1000, 0), intensity=1.5)
|
||||
add_light(self.renderer, (0, 0, 1000), intensity=1.5)
|
||||
add_light(self.renderer, (0, 0, -1000), intensity=1.5)
|
||||
|
||||
|
||||
# Set up picking
|
||||
self.picker = vtk.vtkCellPicker()
|
||||
@@ -81,6 +102,14 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
self.interactor.Initialize()
|
||||
self.interactor.Start()
|
||||
|
||||
def on_receive_command(self, command):
|
||||
"""Calls the individual commands pressed in main"""
|
||||
print("Receive command: ", command)
|
||||
if command == "flip":
|
||||
self.clear_actors_projection()
|
||||
self.flip_toggle = not self.flip_toggle # Toggle the flag
|
||||
self.on_invert_normal()
|
||||
|
||||
@staticmethod
|
||||
def compute_normal_from_lines(line1, line2):
|
||||
vec1 = line1[1] - line1[0]
|
||||
@@ -142,18 +171,17 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(0.0, 0.0, 1.0) # Set color to red
|
||||
actor.GetProperty().SetColor(1.0, 1.0, 1.0)
|
||||
actor.GetProperty().SetLineWidth(2) # Set line width
|
||||
|
||||
# Add the actor to the scene
|
||||
self.renderer.AddActor(actor)
|
||||
#self.renderer.SetBackground(0.1, 0.2, 0.4) # Set background color
|
||||
|
||||
mapper.Update()
|
||||
self.vtk_widget.GetRenderWindow().Render()
|
||||
|
||||
|
||||
def render_from_points_direct_with_faces(self, vertices, faces, color=(1, 1, 1), line_width=2, point_size=5):
|
||||
def render_from_points_direct_with_faces(self, vertices, faces, color=(0.1, 0.2, 0.8), line_width=2, point_size=5):
|
||||
points = vtk.vtkPoints()
|
||||
|
||||
# Use SetData with numpy array
|
||||
@@ -185,6 +213,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
mirror_transform = vtk.vtkTransform()
|
||||
|
||||
if self.local_matrix:
|
||||
"""Transforming to the position of the sketch projection with invert matrix"""
|
||||
print(self.local_matrix)
|
||||
matrix = vtk.vtkMatrix4x4()
|
||||
matrix.DeepCopy(self.local_matrix)
|
||||
@@ -210,7 +239,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(color)
|
||||
actor.GetProperty().EdgeVisibilityOn()
|
||||
actor.GetProperty().EdgeVisibilityOff()
|
||||
actor.GetProperty().SetLineWidth(line_width)
|
||||
|
||||
self.renderer.AddActor(actor)
|
||||
@@ -438,6 +467,11 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
return actor # Return the actor in case you need to remove or modify it later
|
||||
|
||||
def on_invert_normal(self):
|
||||
# Kippstufe für Normal flip
|
||||
if self.selected_normal is not None:
|
||||
self.compute_projection(self.flip_toggle)
|
||||
|
||||
def on_click(self, obj, event):
|
||||
click_pos = self.interactor.GetEventPosition()
|
||||
|
||||
@@ -468,8 +502,8 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
point1 = np.array(proj_point1)
|
||||
point2 = np.array(proj_point2)
|
||||
|
||||
print(f"Line starts at: {point1}")
|
||||
print(f"Line ends at: {point2}")
|
||||
#print(f"Line starts at: {point1}")
|
||||
#print(f"Line ends at: {point2}")
|
||||
|
||||
# Store this line for later use if needed
|
||||
self.selected_edges.append((point1, point2))
|
||||
@@ -493,52 +527,70 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
self.picked_edge_actors.append(edge_actor)
|
||||
|
||||
if len(self.selected_edges) == 2:
|
||||
# Compute the normal from the two selected edges
|
||||
edge1 = self.selected_edges[0][1] - self.selected_edges[0][0]
|
||||
edge2 = self.selected_edges[1][1] - self.selected_edges[1][0]
|
||||
self.selected_normal = np.cross(edge1, edge2)
|
||||
self.selected_normal = self.selected_normal / np.linalg.norm(self.selected_normal)
|
||||
print("Computed normal:", self.selected_normal)
|
||||
|
||||
centroid = np.mean([point for edge in self.selected_edges for point in edge], axis=0)
|
||||
|
||||
# Draw the normal line
|
||||
normal_length = 50 # Adjust this value to change the length of the normal line
|
||||
normal_actor = self.add_normal_line(centroid, self.selected_normal, length=normal_length,
|
||||
color=(1, 0, 0))
|
||||
|
||||
projected_polydata = self.project_mesh_to_plane(polydata, self.selected_normal, centroid)
|
||||
projected_points = projected_polydata.GetPoints()
|
||||
print("proj_points", projected_points)
|
||||
|
||||
# Extract 2D coordinates
|
||||
self.project_tosketch_edge = self.compute_2d_coordinates(projected_polydata, self.selected_normal)
|
||||
print("3d_points_proj", self.project_tosketch_edge)
|
||||
|
||||
# Create a mapper and actor for the projected data
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(projected_polydata)
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(0.0, 1.0, 0.0) # Set color to green
|
||||
actor.GetProperty().SetLineWidth(4) # Set line width
|
||||
|
||||
self.renderer.AddActor(normal_actor)
|
||||
|
||||
# Add the actor to the scene
|
||||
self.renderer.AddActor(actor)
|
||||
|
||||
# Clear selection after
|
||||
self.selected_edges = []
|
||||
self.selected_normal = []
|
||||
for edge_line in self.picked_edge_actors:
|
||||
self.renderer.RemoveActor(edge_line)
|
||||
self.compute_projection(False)
|
||||
|
||||
elif len(self.selected_edges) > 2:
|
||||
pass
|
||||
|
||||
def clear_edge_select(self, ):
|
||||
# Clear selection after projection was succesful
|
||||
self.selected_edges = []
|
||||
self.selected_normal = []
|
||||
|
||||
def clear_actors_projection(self):
|
||||
"""Removes all actors that were used for projection"""
|
||||
for edge_line in self.picked_edge_actors:
|
||||
self.renderer.RemoveActor(edge_line)
|
||||
|
||||
for normals in self.displayed_normal_actors:
|
||||
self.renderer.RemoveActor(normals)
|
||||
|
||||
def compute_projection(self, direction_invert: bool= False):
|
||||
# Compute the normal from the two selected edges )
|
||||
edge1 = self.selected_edges[0][1] - self.selected_edges[0][0]
|
||||
edge2 = self.selected_edges[1][1] - self.selected_edges[1][0]
|
||||
selected_normal = np.cross(edge1, edge2)
|
||||
selected_normal = selected_normal / np.linalg.norm(selected_normal)
|
||||
#print("Computed normal:", self.selected_normal)
|
||||
|
||||
# Invert the normal in local z if direction_invert is True
|
||||
if direction_invert:
|
||||
self.selected_normal = -selected_normal
|
||||
else:
|
||||
self.selected_normal = selected_normal
|
||||
|
||||
centroid = np.mean([point for edge in self.selected_edges for point in edge], axis=0)
|
||||
|
||||
# Draw the normal line
|
||||
normal_length = 50 # Adjust this value to change the length of the normal line
|
||||
normal_actor = self.add_normal_line(centroid, self.selected_normal, length=normal_length,
|
||||
color=(1, 0, 0))
|
||||
|
||||
polydata = self.picker.GetActor().GetMapper().GetInput()
|
||||
|
||||
projected_polydata = self.project_mesh_to_plane(polydata, self.selected_normal, centroid)
|
||||
projected_points = projected_polydata.GetPoints()
|
||||
#print("proj_points", projected_points)
|
||||
|
||||
# Extract 2D coordinates
|
||||
self.project_tosketch_edge = self.compute_2d_coordinates(projected_polydata, self.selected_normal)
|
||||
#print("3d_points_proj", self.project_tosketch_edge)
|
||||
|
||||
# Create a mapper and actor for the projected data
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(projected_polydata)
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(0.0, 1.0, 0.0) # Set color to green
|
||||
actor.GetProperty().SetLineWidth(4) # Set line width
|
||||
|
||||
self.renderer.AddActor(normal_actor)
|
||||
self.displayed_normal_actors.append(normal_actor)
|
||||
|
||||
# Add the actor to the scene
|
||||
self.renderer.AddActor(actor)
|
||||
self.picked_edge_actors.append(actor)
|
||||
|
||||
# Render the scene
|
||||
self.vtk_widget.GetRenderWindow().Render()
|
||||
|
||||
Reference in New Issue
Block a user