Fixed interactor
Added proj lines selected
This commit is contained in:
@@ -5,7 +5,7 @@ from copy import copy
|
||||
import numpy as np
|
||||
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QInputDialog
|
||||
from PySide6.QtGui import QPainter, QPen, QColor, QTransform
|
||||
from PySide6.QtCore import Qt, QPoint, QPointF, Signal
|
||||
from PySide6.QtCore import Qt, QPoint, QPointF, Signal, QLine
|
||||
from python_solvespace import SolverSystem, ResultFlag
|
||||
|
||||
|
||||
@@ -51,13 +51,11 @@ class SketchWidget(QWidget):
|
||||
def create_workplane_projected(self):
|
||||
self.wp = self.solv.create_2d_base()
|
||||
|
||||
def create_proj_lines(self, lines):
|
||||
def create_proj_points(self, proj_points):
|
||||
"""Lines as orientation projected from the sketch"""
|
||||
|
||||
for point in lines:
|
||||
for point in proj_points:
|
||||
x, y = point
|
||||
self.proj_snap_lines = lines
|
||||
# Invert X from projection might be happening in the projection for some reason Careful
|
||||
coord = QPoint(x, y)
|
||||
self.proj_snap_points.append(coord)
|
||||
|
||||
@@ -69,6 +67,24 @@ class SketchWidget(QWidget):
|
||||
|
||||
self.slv_points_main.append(relation_point)"""
|
||||
|
||||
def create_proj_lines(self, sel_edges):
|
||||
"""Lines as orientation projected from the sketch"""
|
||||
print("Incoming corrd lines", sel_edges)
|
||||
for line in sel_edges:
|
||||
|
||||
start = QPoint(line[0][0], line[0][1] )
|
||||
end = QPoint(line[1][0], line[1][1])
|
||||
coord = QLine(start, end)
|
||||
self.proj_snap_lines.append(coord)
|
||||
|
||||
"""relation_point = {} # Reinitialize the dictionary
|
||||
#handle_nr = self.get_handle_nr(str(point))
|
||||
#relation_point['handle_nr'] = handle_nr
|
||||
#relation_point['solv_handle'] = point
|
||||
relation_point['ui_point'] = QPoint(x, y)
|
||||
|
||||
self.slv_points_main.append(relation_point)"""
|
||||
|
||||
def find_duplicate_points_2d(self, edges):
|
||||
points = []
|
||||
seen = set()
|
||||
@@ -675,11 +691,11 @@ class SketchWidget(QWidget):
|
||||
return QPoint(int(widget_x), int(widget_y))
|
||||
|
||||
def from_quadrant_coords_no_center(self, point):
|
||||
"""Translate quadrant coordinates to linear coordinates."""
|
||||
"""Invert Y Coordinate for mesh"""
|
||||
center_x = 0
|
||||
center_y = 0
|
||||
widget_x = center_x + point.x() * self.zoom
|
||||
widget_y = center_y - point.y() * self.zoom # Note the subtraction here
|
||||
widget_x = point.x()
|
||||
widget_y = -point.y()
|
||||
return QPoint(int(widget_x), int(widget_y))
|
||||
|
||||
def paintEvent(self, event):
|
||||
@@ -746,6 +762,11 @@ class SketchWidget(QWidget):
|
||||
for cross in self.proj_snap_points:
|
||||
self.draw_cross(painter, cross, 10 / self.zoom)
|
||||
|
||||
for selected in self.proj_snap_lines:
|
||||
pen = QPen(Qt.white, 1, Qt.DashLine)
|
||||
painter.setPen(pen)
|
||||
painter.drawLine(selected)
|
||||
|
||||
painter.end()
|
||||
|
||||
def wheelEvent(self, event):
|
||||
|
||||
@@ -13,6 +13,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.selected_vtk_line = []
|
||||
self.access_selected_points = []
|
||||
self.selected_normal = None
|
||||
self.centroid = None
|
||||
@@ -21,7 +22,8 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
self.local_matrix = None
|
||||
|
||||
self.project_tosketch_edge = []
|
||||
self.project_tosketch_points = []
|
||||
self.project_tosketch_lines = []
|
||||
|
||||
self.vtk_widget = QVTKRenderWindowInteractor(self)
|
||||
|
||||
@@ -112,10 +114,12 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
mapper.SetInputData(grid)
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetPickable(False)
|
||||
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()
|
||||
@@ -169,7 +173,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
normal = normal / np.linalg.norm(normal)
|
||||
return normal
|
||||
|
||||
def load_interactor_mesh(self, edges):
|
||||
def load_interactor_mesh(self, edges, off_vector):
|
||||
# Create vtkPoints to store all points
|
||||
points = vtk.vtkPoints()
|
||||
|
||||
@@ -195,28 +199,34 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
polydata.SetLines(lines)
|
||||
|
||||
# Create a transform for mirroring across the y-axis
|
||||
mirror_transform = vtk.vtkTransform()
|
||||
matrix_transform = vtk.vtkTransform()
|
||||
|
||||
"""if self.local_matrix:
|
||||
if self.local_matrix:
|
||||
print(self.local_matrix)
|
||||
matrix = vtk.vtkMatrix4x4()
|
||||
matrix.DeepCopy(self.local_matrix)
|
||||
matrix.Invert()
|
||||
mirror_transform.SetMatrix(matrix)
|
||||
matrix_transform.SetMatrix(matrix)
|
||||
#matrix_transform.Scale(1, 1, 1) # This mirrors across the y-axis
|
||||
|
||||
mirror_transform.Scale(-1, -1, 1) # Inverting the original mirror look down
|
||||
|
||||
mirror_transform.Scale(1, 1, 1) # This mirrors across the y-axis"""
|
||||
|
||||
# Apply the transform to the polydata
|
||||
# Apply the matrix transform
|
||||
transformFilter = vtk.vtkTransformPolyDataFilter()
|
||||
transformFilter.SetInputData(polydata)
|
||||
transformFilter.SetTransform(mirror_transform)
|
||||
transformFilter.SetTransform(matrix_transform)
|
||||
transformFilter.Update()
|
||||
|
||||
# Create and apply the offset transform
|
||||
offset_transform = vtk.vtkTransform()
|
||||
offset_transform.Translate(off_vector[0], off_vector[1], off_vector[2])
|
||||
|
||||
offsetFilter = vtk.vtkTransformPolyDataFilter()
|
||||
offsetFilter.SetInputConnection(transformFilter.GetOutputPort())
|
||||
offsetFilter.SetTransform(offset_transform)
|
||||
offsetFilter.Update()
|
||||
|
||||
# Create a mapper and actor
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
mapper.SetInputData(transformFilter.GetOutput())
|
||||
mapper.SetInputConnection(offsetFilter.GetOutputPort())
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
@@ -270,6 +280,9 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
actor.GetProperty().SetColor(color)
|
||||
actor.GetProperty().EdgeVisibilityOff()
|
||||
actor.GetProperty().SetLineWidth(line_width)
|
||||
actor.GetProperty().SetMetallic(1)
|
||||
actor.GetProperty().SetOpacity(0.8)
|
||||
actor.SetPickable(False)
|
||||
|
||||
self.renderer.AddActor(actor)
|
||||
self.body_actors_orig.append(actor)
|
||||
@@ -385,6 +398,62 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
return xy_coordinates
|
||||
|
||||
def compute_2d_coordinates_line(self, line_cell, normal):
|
||||
# Ensure the input is a vtkLine
|
||||
if not isinstance(line_cell, vtk.vtkLine):
|
||||
raise ValueError("Input must be a vtkLine cell")
|
||||
|
||||
# Normalize the normal vector
|
||||
normal = np.array(normal)
|
||||
normal = normal / np.linalg.norm(normal)
|
||||
|
||||
# Create a vtkTransform
|
||||
transform = vtk.vtkTransform()
|
||||
transform.PostMultiply() # This ensures transforms are applied in the order we specify
|
||||
|
||||
# Rotate so that the normal aligns with the Z-axis
|
||||
rotation_axis = np.cross(normal, [0, 0, 1])
|
||||
angle = np.arccos(np.dot(normal, [0, 0, 1])) * 180 / np.pi # Convert to degrees
|
||||
|
||||
if np.linalg.norm(rotation_axis) > 1e-6: # Check if rotation is needed
|
||||
transform.RotateWXYZ(angle, rotation_axis[0], rotation_axis[1], rotation_axis[2])
|
||||
|
||||
# Get the transformation matrix
|
||||
matrix = transform.GetMatrix()
|
||||
local_matrix = [matrix.GetElement(i, j) for i in range(4) for j in range(4)]
|
||||
|
||||
# Create a vtkPoints object to store the line points
|
||||
points = vtk.vtkPoints()
|
||||
points.InsertNextPoint(line_cell.GetPoints().GetPoint(0))
|
||||
points.InsertNextPoint(line_cell.GetPoints().GetPoint(1))
|
||||
|
||||
# Create a vtkPolyData to represent the line
|
||||
polydata = vtk.vtkPolyData()
|
||||
polydata.SetPoints(points)
|
||||
|
||||
# Create a vtkCellArray to store the line cell
|
||||
cells = vtk.vtkCellArray()
|
||||
cells.InsertNextCell(line_cell)
|
||||
polydata.SetLines(cells)
|
||||
|
||||
# Apply the transform to the polydata
|
||||
transform_filter = vtk.vtkTransformPolyDataFilter()
|
||||
transform_filter.SetInputData(polydata)
|
||||
transform_filter.SetTransform(transform)
|
||||
transform_filter.Update()
|
||||
|
||||
# Get the transformed points
|
||||
transformed_polydata = transform_filter.GetOutput()
|
||||
transformed_points = transformed_polydata.GetPoints()
|
||||
|
||||
# Extract 2D coordinates
|
||||
xy_coordinates = []
|
||||
for i in range(transformed_points.GetNumberOfPoints()):
|
||||
point = transformed_points.GetPoint(i)
|
||||
xy_coordinates.append((point[0], point[1]))
|
||||
|
||||
return xy_coordinates
|
||||
|
||||
def project_2d_to_3d(self, xy_coordinates, normal):
|
||||
# Normalize the normal vector
|
||||
normal = np.array(normal)
|
||||
@@ -494,6 +563,8 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
# Ensure it's a line
|
||||
if cell.GetCellType() == vtk.VTK_LINE:
|
||||
self.selected_vtk_line.append(cell)
|
||||
|
||||
# Get the two points of the line
|
||||
point_id1 = cell.GetPointId(0)
|
||||
point_id2 = cell.GetPointId(1)
|
||||
@@ -533,9 +604,11 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
if len(self.selected_edges) == 2:
|
||||
self.compute_projection(False)
|
||||
|
||||
elif len(self.selected_edges) > 2:
|
||||
del self.selected_edges[0]
|
||||
pass
|
||||
if len(self.selected_edges) > 2:
|
||||
self.selected_vtk_line.clear()
|
||||
self.selected_edges.clear()
|
||||
self.clear_actors_projection()
|
||||
self.clear_edge_select()
|
||||
|
||||
def find_origin_vertex(self, edge1, edge2):
|
||||
if edge1[0] == edge2[0]or edge1[0] == edge2[1]:
|
||||
@@ -559,6 +632,7 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
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]
|
||||
@@ -583,11 +657,14 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
polydata = self.picker.GetActor().GetMapper().GetInput()
|
||||
|
||||
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_points = self.compute_2d_coordinates(projected_polydata, self.selected_normal)
|
||||
|
||||
# Seperately rotate selected edges for drawing
|
||||
for vtk_line in self.selected_vtk_line:
|
||||
proj_vtk_line = self.compute_2d_coordinates_line(vtk_line, self.selected_normal)
|
||||
self.project_tosketch_lines.append(proj_vtk_line)
|
||||
|
||||
# Create a mapper and actor for the projected data
|
||||
mapper = vtk.vtkPolyDataMapper()
|
||||
@@ -595,13 +672,14 @@ class VTKWidget(QtWidgets.QWidget):
|
||||
|
||||
actor = vtk.vtkActor()
|
||||
actor.SetMapper(mapper)
|
||||
#actor.GetProperty().SetRenderLinesAsTubes(True)
|
||||
actor.GetProperty().SetColor(0.0, 1.0, 0.0) # Set color to green
|
||||
actor.GetProperty().SetLineWidth(4) # Set line width
|
||||
actor.GetProperty().SetLineWidth(8) # Set line width
|
||||
|
||||
self.renderer.AddActor(normal_actor)
|
||||
self.displayed_normal_actors.append(normal_actor)
|
||||
|
||||
# Add the actor to the scene
|
||||
# Add the edge lines actor to the scene
|
||||
self.renderer.AddActor(actor)
|
||||
self.picked_edge_actors.append(actor)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user