- Basic 2D projection

This commit is contained in:
bklronin 2024-07-09 15:45:34 +02:00
parent 5ff48c0f5e
commit b5c965bf2e
3 changed files with 75 additions and 15 deletions

View File

@ -72,7 +72,6 @@ class SketchWidget(QWidget):
print("lines", self.slv_lines_main)
print("lines", lines)
def find_duplicate_points_2d(self, edges):
points = []
seen = set()

View File

@ -17,8 +17,13 @@ class VTKWidget(QtWidgets.QWidget):
self.selected_normal = None
self.selected_edges = []
self.cell_normals = None
self.project_tosketch_edge = []
self.vtk_widget = QVTKRenderWindowInteractor(self)
self.picked_edge_actors = []
# Create layout and add VTK widget
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.vtk_widget)
@ -43,8 +48,12 @@ class VTKWidget(QtWidgets.QWidget):
self.picked_actor = vtk.vtkActor()
self.picked_actor.SetMapper(self.picked_mapper)
self.picked_actor.GetProperty().SetColor(1.0, 0.0, 0.0) # Red color for picked faces
self.picked_actor.VisibilityOff() # Initially hide the actor
self.renderer.AddActor(self.picked_actor)
# Create an extract selection filter
self.extract_selection = vtk.vtkExtractSelection()
# Set up interactor style
self.style = vtk.vtkInteractorStyleTrackballCamera()
self.interactor.SetInteractorStyle(self.style)
@ -86,15 +95,11 @@ class VTKWidget(QtWidgets.QWidget):
polydata.SetPoints(points)
polydata.SetLines(lines)
# Verify that the polydata is not empty
if polydata.GetNumberOfPoints() == 0 or polydata.GetNumberOfCells() == 0:
print("Error: PolyData is empty")
sys.exit(1)
# Create a mapper and actor
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polydata)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0.0, 0.0, 1.0) # Set color to red
@ -104,9 +109,7 @@ class VTKWidget(QtWidgets.QWidget):
self.renderer.AddActor(actor)
#self.renderer.SetBackground(0.1, 0.2, 0.4) # Set background color
# Render and interact
# Force an update of the pipeline
# mapper.Update()
mapper.Update()
self.vtk_widget.GetRenderWindow().Render()
def render_from_points_direct_with_faces(self, vertices, faces):
@ -190,6 +193,25 @@ class VTKWidget(QtWidgets.QWidget):
mapper.Update()
self.vtk_widget.GetRenderWindow().Render()
def get_points_and_edges_from_polydata(self, polydata) -> list:
# Extract points
points = {}
vtk_points = polydata.GetPoints()
for i in range(vtk_points.GetNumberOfPoints()):
point = vtk_points.GetPoint(i)
points[i] = np.array(point)
# Extract edges
edges = []
for i in range(polydata.GetNumberOfCells()):
cell = polydata.GetCell(i)
if cell.GetCellType() == vtk.VTK_LINE:
point_ids = cell.GetPointIds()
edge = (point_ids.GetId(0), point_ids.GetId(1))
edges.append(edge)
return points, edges
def on_click(self, obj, event):
click_pos = self.interactor.GetEventPosition()
@ -226,6 +248,24 @@ class VTKWidget(QtWidgets.QWidget):
# Store this line for later use if needed
self.selected_edges.append((point1, point2))
# Create a new vtkLineSource for the picked edge
line_source = vtk.vtkLineSource()
line_source.SetPoint1(point1)
line_source.SetPoint2(point2)
# Create a mapper and actor for the picked edge
edge_mapper = vtk.vtkPolyDataMapper()
edge_mapper.SetInputConnection(line_source.GetOutputPort())
edge_actor = vtk.vtkActor()
edge_actor.SetMapper(edge_mapper)
edge_actor.GetProperty().SetColor(1.0, 0.0, 0.0) # Red color for picked edges
edge_actor.GetProperty().SetLineWidth(4) # Make the line thicker
# Add the actor to the renderer and store it
self.renderer.AddActor(edge_actor)
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]
@ -234,10 +274,17 @@ class VTKWidget(QtWidgets.QWidget):
self.selected_normal = self.selected_normal / np.linalg.norm(self.selected_normal)
print("Computed normal:", self.selected_normal)
# Compute the centroid of the selected edges
centroid = (
0, 0, 0) # point1 #np.mean([point for edge in self.selected_edges for point in edge], axis=0)
# Create a transform for projection
transform = vtk.vtkTransform()
transform.Identity()
# Translate to center the transform on the centroid
transform.Translate(-centroid[0], -centroid[1], -centroid[2])
# Compute rotation to align normal with Z-axis
z_axis = np.array([0, 0, 1])
rotation_axis = np.cross(self.selected_normal, z_axis)
@ -252,6 +299,9 @@ class VTKWidget(QtWidgets.QWidget):
# Apply the inverse rotation to bring it back to original orientation
transform.RotateWXYZ(-rotation_angle, rotation_axis[0], rotation_axis[1], rotation_axis[2])
# Translate back
transform.Translate(centroid[0], centroid[1], centroid[2])
# Apply the transform to the polydata
transformFilter = vtk.vtkTransformPolyDataFilter()
transformFilter.SetInputData(polydata)
@ -260,6 +310,7 @@ class VTKWidget(QtWidgets.QWidget):
# Get the projected polydata
projected_polydata = transformFilter.GetOutput()
print("Polydata", projected_polydata)
# Create a mapper and actor for the projected data
mapper = vtk.vtkPolyDataMapper()
@ -275,7 +326,7 @@ class VTKWidget(QtWidgets.QWidget):
# Add a plane to visualize the projection plane
plane_source = vtk.vtkPlaneSource()
plane_source.SetCenter(0, 0, 0)
plane_source.SetCenter(centroid)
plane_source.SetNormal(self.selected_normal)
plane_mapper = vtk.vtkPolyDataMapper()
plane_mapper.SetInputConnection(plane_source.GetOutputPort())
@ -291,13 +342,23 @@ class VTKWidget(QtWidgets.QWidget):
# Render and interact
self.vtk_widget.GetRenderWindow().Render()
# Reset selected edges
self.selected_edges = []
self.project_tosketch_edge = self.get_points_and_edges_from_polydata(projected_polydata)
print("Edges", self.project_tosketch_edge[0])
elif len(self.access_selected_points) > 2:
self.access_selected_points = []
# Clear the picked edge actors
for actor in self.picked_edge_actors:
self.renderer.RemoveActor(actor)
self.picked_edge_actors.clear()
# Reset selected edges
self.selected_edges = []
else:
print("Selected cell is not a line")
# Render the scene
self.vtk_widget.GetRenderWindow().Render()
def start(self):
self.interactor.Initialize()
self.interactor.Start()

View File

@ -74,8 +74,8 @@ class MainWindow(QMainWindow):
def add_new_sketch_wp(self):
self.sketchWidget.clear_sketch()
edges = [((-158.0, -20.0, -25.0), (286.0, -195.0, -25.0)), ((-158.0, -20.0, 25.0), (-158.0, -20.0, -25.0))]
#edges = self.custom_3D_Widget.access_selected_points
#edges = [((-158.0, -20.0, -25.0), (286.0, -195.0, -25.0)), ((-158.0, -20.0, 25.0), (-158.0, -20.0, -25.0))]
edges = self.custom_3D_Widget.project_tosketch_edge
normal = self.custom_3D_Widget.selected_normal
self.sketchWidget.create_workplane_projected()
@ -310,7 +310,7 @@ class MainWindow(QMainWindow):
items = self.ui.body_list.findItems(name_op, Qt.MatchExactly)[0]
self.ui.body_list.setCurrentItem(items)
self.calc_sketch_projection_3d(lines, 0, length)
#self.draw_mesh()
self.draw_mesh()
def send_cut(self):
name = self.ui.body_list.currentItem().text()