- Fixed 2d sketch with transfrom
This commit is contained in:
@@ -15,6 +15,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
super().__init__(parent)
|
||||
self.access_selected_points = []
|
||||
self.selected_normal = None
|
||||
self.centroid = None
|
||||
self.selected_edges = []
|
||||
self.cell_normals = None
|
||||
|
||||
@@ -26,6 +27,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
self.picked_edge_actors = []
|
||||
self.displayed_normal_actors = []
|
||||
self.body_actors_orig = []
|
||||
|
||||
self.flip_toggle = False
|
||||
|
||||
@@ -102,6 +104,54 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
self.interactor.Initialize()
|
||||
self.interactor.Start()
|
||||
|
||||
# Create the grid
|
||||
grid = self.create_grid(size=100, spacing=10)
|
||||
|
||||
# Setup actor and mapper
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(grid)
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(0.5, 0.5, 0.5) # Set grid color to gray
|
||||
|
||||
self.renderer.AddActor(actor)
|
||||
def create_grid(self, size=100, spacing=10):
|
||||
# Create a vtkPoints object and store the points in it
|
||||
points = vtk.vtkPoints()
|
||||
|
||||
# Create lines
|
||||
lines = vtk.vtkCellArray()
|
||||
|
||||
# Create the grid
|
||||
for i in range(-size, size + 1, spacing):
|
||||
# X-direction line
|
||||
points.InsertNextPoint(i, -size, 0)
|
||||
points.InsertNextPoint(i, size, 0)
|
||||
line = vtk.vtkLine()
|
||||
line.GetPointIds().SetId(0, points.GetNumberOfPoints() - 2)
|
||||
line.GetPointIds().SetId(1, points.GetNumberOfPoints() - 1)
|
||||
lines.InsertNextCell(line)
|
||||
|
||||
# Y-direction line
|
||||
points.InsertNextPoint(-size, i, 0)
|
||||
points.InsertNextPoint(size, i, 0)
|
||||
line = vtk.vtkLine()
|
||||
line.GetPointIds().SetId(0, points.GetNumberOfPoints() - 2)
|
||||
line.GetPointIds().SetId(1, points.GetNumberOfPoints() - 1)
|
||||
lines.InsertNextCell(line)
|
||||
|
||||
# Create a polydata to store everything in
|
||||
grid = vtk.vtkPolyData()
|
||||
|
||||
# Add the points to the dataset
|
||||
grid.SetPoints(points)
|
||||
|
||||
# Add the lines to the dataset
|
||||
grid.SetLines(lines)
|
||||
|
||||
return grid
|
||||
|
||||
def on_receive_command(self, command):
|
||||
"""Calls the individual commands pressed in main"""
|
||||
print("Receive command: ", command)
|
||||
@@ -147,7 +197,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
# Create a transform for mirroring across the y-axis
|
||||
mirror_transform = vtk.vtkTransform()
|
||||
|
||||
if self.local_matrix:
|
||||
"""if self.local_matrix:
|
||||
print(self.local_matrix)
|
||||
matrix = vtk.vtkMatrix4x4()
|
||||
matrix.DeepCopy(self.local_matrix)
|
||||
@@ -156,8 +206,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
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
|
||||
mirror_transform.Scale(1, 1, 1) # This mirrors across the y-axis"""
|
||||
|
||||
# Apply the transform to the polydata
|
||||
transformFilter = vtk.vtkTransformPolyDataFilter()
|
||||
@@ -172,7 +221,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
actor.GetProperty().SetColor(1.0, 1.0, 1.0)
|
||||
actor.GetProperty().SetLineWidth(2) # Set line width
|
||||
actor.GetProperty().SetLineWidth(4) # Set line width
|
||||
|
||||
# Add the actor to the scene
|
||||
self.renderer.AddActor(actor)
|
||||
@@ -180,8 +229,9 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
mapper.Update()
|
||||
self.vtk_widget.GetRenderWindow().Render()
|
||||
|
||||
|
||||
def render_from_points_direct_with_faces(self, vertices, faces, color=(0.1, 0.2, 0.8), line_width=2, point_size=5):
|
||||
"""Sketch Widget has inverted Y axiis therefore we invert y via scale here until fix"""
|
||||
|
||||
points = vtk.vtkPoints()
|
||||
|
||||
# Use SetData with numpy array
|
||||
@@ -209,32 +259,11 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
normalGenerator.ComputeCellNormalsOn()
|
||||
normalGenerator.Update()
|
||||
|
||||
# Create a transform for mirroring across the y-axis
|
||||
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)
|
||||
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()
|
||||
transformFilter.SetInputData(polydata)
|
||||
transformFilter.SetTransform(mirror_transform)
|
||||
transformFilter.Update()
|
||||
|
||||
self.cell_normals = vtk_to_numpy(normalGenerator.GetOutput().GetCellData().GetNormals())
|
||||
|
||||
# Create a mapper and actor
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(transformFilter.GetOutput())
|
||||
mapper.SetInputData(polydata)
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
@@ -243,8 +272,13 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
actor.GetProperty().SetLineWidth(line_width)
|
||||
|
||||
self.renderer.AddActor(actor)
|
||||
self.body_actors_orig.append(actor)
|
||||
self.vtk_widget.GetRenderWindow().Render()
|
||||
|
||||
def clear_body_actors(self):
|
||||
for actor in self.body_actors_orig:
|
||||
self.renderer.RemoveActor(actor)
|
||||
|
||||
def visualize_matrix(self, matrix):
|
||||
points = vtk.vtkPoints()
|
||||
for i in range(4):
|
||||
@@ -277,40 +311,6 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
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
|
||||
points = vtk.vtkPoints()
|
||||
for vertex in vertices:
|
||||
points.InsertNextPoint(vertex)
|
||||
|
||||
# Create a vtkCellArray to store the faces
|
||||
cells = vtk.vtkCellArray()
|
||||
for face in faces:
|
||||
triangle = vtk.vtkTriangle()
|
||||
triangle.GetPointIds().SetId(0, face[0])
|
||||
triangle.GetPointIds().SetId(1, face[1])
|
||||
triangle.GetPointIds().SetId(2, face[2])
|
||||
cells.InsertNextCell(triangle)
|
||||
|
||||
# Create a polydata object
|
||||
polydata = vtk.vtkPolyData()
|
||||
polydata.SetPoints(points)
|
||||
polydata.SetPolys(cells)
|
||||
|
||||
# Create mapper and actor
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(polydata) # Make sure this line is present
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
|
||||
# Add to renderer
|
||||
self.renderer.AddActor(actor)
|
||||
|
||||
# Force an update of the pipeline
|
||||
mapper.Update()
|
||||
self.vtk_widget.GetRenderWindow().Render()
|
||||
|
||||
def get_points_and_edges_from_polydata(self, polydata) -> list:
|
||||
# Extract points
|
||||
points = {}
|
||||
@@ -353,7 +353,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
center_of_mass.SetInputData(projected_mesh)
|
||||
center_of_mass.SetUseScalarsAsWeights(False)
|
||||
center_of_mass.Update()
|
||||
centroid = center_of_mass.GetCenter()
|
||||
centroid = np.array(center_of_mass.GetCenter())
|
||||
|
||||
# Create a coordinate system on the plane
|
||||
z_axis = np.array(normal)
|
||||
@@ -363,68 +363,33 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
x_axis = x_axis / np.linalg.norm(x_axis)
|
||||
y_axis = np.cross(z_axis, x_axis)
|
||||
|
||||
# Create transformation matrix
|
||||
matrix = vtk.vtkMatrix4x4()
|
||||
for i in range(3):
|
||||
matrix.SetElement(i, 0, x_axis[i])
|
||||
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()
|
||||
# Create rotation matrix (3x3)
|
||||
rotation_matrix = np.column_stack((x_axis, y_axis, z_axis))
|
||||
|
||||
# Store the full transformation for later use if needed
|
||||
full_transform = np.eye(4)
|
||||
full_transform[:3, :3] = rotation_matrix
|
||||
full_transform[:3, 3] = centroid
|
||||
self.local_matrix = full_transform
|
||||
|
||||
# Transform points to 2D coordinates
|
||||
transform = vtk.vtkTransform()
|
||||
transform.SetMatrix(matrix)
|
||||
transform.Scale([1,1,1])
|
||||
|
||||
transformer = vtk.vtkTransformPolyDataFilter()
|
||||
transformer.SetInputData(projected_mesh)
|
||||
transformer.SetTransform(transform)
|
||||
transformer.Update()
|
||||
|
||||
transformed_mesh = transformer.GetOutput()
|
||||
points = transformed_mesh.GetPoints()
|
||||
|
||||
points = projected_mesh.GetPoints()
|
||||
xy_coordinates = []
|
||||
|
||||
for i in range(points.GetNumberOfPoints()):
|
||||
point = points.GetPoint(i)
|
||||
xy_coordinates.append((-point[0], point[1]))
|
||||
point = np.array(points.GetPoint(i))
|
||||
|
||||
# Translate point to origin
|
||||
point_centered = point - centroid
|
||||
|
||||
# Rotate point
|
||||
rotated_point = np.dot(rotation_matrix.T, point_centered)
|
||||
|
||||
# Store only x and y coordinates
|
||||
xy_coordinates.append((rotated_point[0], rotated_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)
|
||||
@@ -520,7 +485,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
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
|
||||
edge_actor.GetProperty().SetLineWidth(8) # Make the line thicker
|
||||
|
||||
# Add the actor to the renderer and store it
|
||||
self.renderer.AddActor(edge_actor)
|
||||
@@ -530,9 +495,18 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
self.compute_projection(False)
|
||||
|
||||
elif len(self.selected_edges) > 2:
|
||||
del self.selected_edges[0]
|
||||
pass
|
||||
|
||||
def clear_edge_select(self, ):
|
||||
def find_origin_vertex(self, edge1, edge2):
|
||||
if edge1[0] == edge2[0]or edge1[0] == edge2[1]:
|
||||
return edge1[0]
|
||||
elif edge1[1] == edge2[0] or edge1[1] == edge2[1]:
|
||||
return edge1[1]
|
||||
else:
|
||||
return None # The edges don't share a vertex
|
||||
|
||||
def clear_edge_select(self ):
|
||||
# Clear selection after projection was succesful
|
||||
self.selected_edges = []
|
||||
self.selected_normal = []
|
||||
@@ -559,21 +533,22 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
else:
|
||||
self.selected_normal = selected_normal
|
||||
|
||||
centroid = np.mean([point for edge in self.selected_edges for point in edge], axis=0)
|
||||
self.centroid = np.mean([point for edge in self.selected_edges for point in edge], axis=0)
|
||||
#self.centroid = self.find_origin_vertex(edge1, edge2)
|
||||
|
||||
# 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,
|
||||
normal_actor = self.add_normal_line(self.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_polydata = self.project_mesh_to_plane(polydata, self.selected_normal, self.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)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user