- Working project and draw on exiting

This commit is contained in:
bklronin
2024-07-11 20:16:20 +02:00
parent cb471b4108
commit d2b8d9540a
4 changed files with 256 additions and 55 deletions

View File

@@ -637,7 +637,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.setWidth(2) # Set the line width
pen.setWidth(int(2 / self.zoom)) # Set the line widt)h
painter.setPen(pen)
# Calculate the endpoints of the cross
@@ -677,10 +677,6 @@ class SketchWidget(QWidget):
for point in self.slv_points_main:
painter.drawEllipse(point['ui_point'], 3 / self.zoom, 3 / self.zoom)
for cross in self.proj_snap_points:
# Calculate the endpoints of the cross
self.draw_cross(painter, cross[0], cross[1], 10)
for dic in self.slv_lines_main:
p1 = dic['ui_points'][0]
p2 = dic['ui_points'][1]
@@ -716,6 +712,10 @@ class SketchWidget(QWidget):
painter.setPen(QPen(Qt.red, 2))
painter.drawLine(p1, p2)
for cross in self.proj_snap_points:
# Calculate the endpoints of the cross
self.draw_cross(painter, cross[0], cross[1], 10)
# self.drawBackgroundGrid(painter)
painter.end()

View File

@@ -18,6 +18,8 @@ class VTKWidget(QtWidgets.QWidget):
self.selected_edges = []
self.cell_normals = None
self.local_matrix = None
self.project_tosketch_edge = []
self.vtk_widget = QVTKRenderWindowInteractor(self)
@@ -113,10 +115,30 @@ class VTKWidget(QtWidgets.QWidget):
polydata.SetPoints(points)
polydata.SetLines(lines)
# Create a transform for mirroring across the y-axis
mirror_transform = vtk.vtkTransform()
if self.local_matrix:
print(self.local_matrix)
matrix = vtk.vtkMatrix4x4()
matrix.DeepCopy(self.local_matrix)
matrix.Invert()
mirror_transform.SetMatrix(matrix)
mirror_transform.Scale(-1, -1, 1) # Inverting the original mirror look down
else:
pass
#mirror_transform.Scale(1, -1, 1) # This mirrors across the y-axis
# Apply the transform to the polydata
transformFilter = vtk.vtkTransformPolyDataFilter()
transformFilter.SetInputData(polydata)
transformFilter.SetTransform(mirror_transform)
transformFilter.Update()
# Create a mapper and actor
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polydata)
mapper.SetInputData(transformFilter.GetOutput())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
@@ -130,18 +152,21 @@ class VTKWidget(QtWidgets.QWidget):
mapper.Update()
self.vtk_widget.GetRenderWindow().Render()
def render_from_points_direct_with_faces(self, vertices, faces):
def render_from_points_direct_with_faces(self, vertices, faces, color=(1, 1, 1), line_width=2, point_size=5):
points = vtk.vtkPoints()
for i in range(vertices.shape[0]):
points.InsertNextPoint(vertices[i])
# Use SetData with numpy array
vtk_array = numpy_to_vtk(vertices, deep=True)
points.SetData(vtk_array)
# Create a vtkCellArray to store the triangles
triangles = vtk.vtkCellArray()
for i in range(faces.shape[0]):
for face in faces:
triangle = vtk.vtkTriangle()
triangle.GetPointIds().SetId(0, faces[i, 0])
triangle.GetPointIds().SetId(1, faces[i, 1])
triangle.GetPointIds().SetId(2, faces[i, 2])
triangle.GetPointIds().SetId(0, face[0])
triangle.GetPointIds().SetId(1, face[1])
triangle.GetPointIds().SetId(2, face[2])
triangles.InsertNextCell(triangle)
# Create a polydata object
@@ -156,11 +181,19 @@ class VTKWidget(QtWidgets.QWidget):
normalGenerator.ComputeCellNormalsOn()
normalGenerator.Update()
### There might be aproblem earlier but this fixes the drawing for now.
#TODO: Investigate upstream conversion errors.
# Create a transform for mirroring across the x-axis
# Create a transform for mirroring across the y-axis
mirror_transform = vtk.vtkTransform()
mirror_transform.Scale(-1, -1, 1) # This mirrors across the x-axis
if self.local_matrix:
print(self.local_matrix)
matrix = vtk.vtkMatrix4x4()
matrix.DeepCopy(self.local_matrix)
matrix.Invert()
mirror_transform.SetMatrix(matrix)
mirror_transform.Scale(-1, 1, 1) #Inverting the original mirror look down
else:
mirror_transform.Scale(1, -1, 1) # This mirrors across the y-axis
# Apply the transform to the polydata
transformFilter = vtk.vtkTransformPolyDataFilter()
@@ -176,19 +209,45 @@ class VTKWidget(QtWidgets.QWidget):
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(1, 1, 1) # Set color (white in this case)
actor.GetProperty().EdgeVisibilityOn() # Show edges
actor.GetProperty().SetLineWidth(2) # Set line width
actor.GetProperty().SetColor(color)
actor.GetProperty().EdgeVisibilityOn()
actor.GetProperty().SetLineWidth(line_width)
# (assuming you have the original mesh mapper and actor set up)
self.renderer.AddActor(actor) # Add the original mesh actor
# Add the edge actor to the renderer
# Force an update of the pipeline
#mapper.Update()
self.renderer.AddActor(actor)
self.vtk_widget.GetRenderWindow().Render()
def visualize_matrix(self, matrix):
points = vtk.vtkPoints()
for i in range(4):
for j in range(4):
points.InsertNextPoint(matrix.GetElement(0, j),
matrix.GetElement(1, j),
matrix.GetElement(2, j))
polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polydata)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetPointSize(5)
self.renderer.AddActor(actor)
def numpy_to_vtk(self, array, deep=True):
"""Convert a numpy array to a vtk array."""
vtk_array = vtk.vtkDoubleArray()
vtk_array.SetNumberOfComponents(array.shape[1])
vtk_array.SetNumberOfTuples(array.shape[0])
for i in range(array.shape[0]):
for j in range(array.shape[1]):
vtk_array.SetComponent(i, j, array[i, j])
return vtk_array
def load_custom_mesh(self, vertices, faces):
### Load meshes by own module
# Create a vtkPoints object and store the points in it
@@ -282,11 +341,13 @@ class VTKWidget(QtWidgets.QWidget):
matrix.SetElement(i, 1, y_axis[i])
matrix.SetElement(i, 2, z_axis[i])
matrix.SetElement(i, 3, centroid[i])
self.local_matrix = matrix
matrix.Invert()
# Transform points to 2D coordinates
transform = vtk.vtkTransform()
transform.SetMatrix(matrix)
transform.Scale([1,1,1])
transformer = vtk.vtkTransformPolyDataFilter()
transformer.SetInputData(projected_mesh)
@@ -299,10 +360,84 @@ class VTKWidget(QtWidgets.QWidget):
xy_coordinates = []
for i in range(points.GetNumberOfPoints()):
point = points.GetPoint(i)
xy_coordinates.append((point[0], point[1]))
xy_coordinates.append((-point[0], point[1]))
return xy_coordinates
def create_normal_gizmo(self, normal, scale=1.0):
# Normalize the normal vector
normal = np.array(normal)
normal = normal / np.linalg.norm(normal)
# Create an arrow source
arrow_source = vtk.vtkArrowSource()
arrow_source.SetTipResolution(20)
arrow_source.SetShaftResolution(20)
# Create a transform to orient and position the arrow
transform = vtk.vtkTransform()
# Translate to the origin point
transform.SetMatrix(self.local_matrix)
# Apply the transform to the arrow
transform_filter = vtk.vtkTransformPolyDataFilter()
transform_filter.SetInputConnection(arrow_source.GetOutputPort())
transform_filter.SetTransform(transform)
transform_filter.Update()
# Create mapper and actor
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(transform_filter.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(1, 0, 0) # Red color for the arrow
return actor
def add_normal_line(self, origin, normal, length=10.0, color=(1, 0, 0)):
# Normalize the normal vector
normal = np.array(normal)
normal = normal / np.linalg.norm(normal)
# Calculate the end point
end_point = origin + normal * length
# Create vtkPoints
points = vtk.vtkPoints()
points.InsertNextPoint(origin)
points.InsertNextPoint(end_point)
# Create a line
line = vtk.vtkLine()
line.GetPointIds().SetId(0, 0)
line.GetPointIds().SetId(1, 1)
# Create a cell array to store the line
lines = vtk.vtkCellArray()
lines.InsertNextCell(line)
# Create a polydata to store everything in
polyData = vtk.vtkPolyData()
polyData.SetPoints(points)
polyData.SetLines(lines)
# Create mapper and actor
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(polyData)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(color)
actor.GetProperty().SetLineWidth(2) # Adjust line width as needed
# Add to renderer
self.renderer.AddActor(actor)
self.vtk_widget.GetRenderWindow().Render()
return actor # Return the actor in case you need to remove or modify it later
def on_click(self, obj, event):
click_pos = self.interactor.GetEventPosition()
@@ -367,6 +502,11 @@ class VTKWidget(QtWidgets.QWidget):
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)
@@ -384,12 +524,20 @@ class VTKWidget(QtWidgets.QWidget):
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)
if len(self.selected_edges) > 2:
# Clear selection after
self.selected_edges = []
self.selected_normal = []
for edge_line in self.picked_edge_actors:
self.renderer.RemoveActor(edge_line)
elif len(self.selected_edges) > 2:
pass
# Render the scene