Layered rendering

inverted interactor
Befrore fork
This commit is contained in:
bklronin
2024-07-18 20:42:01 +02:00
parent a8d15d7b4b
commit df336aaea7
3 changed files with 144 additions and 46 deletions

View File

@@ -780,10 +780,11 @@ class SketchWidget(QWidget):
def clear_sketch(self):
self.slv_points_main = []
self.slv_lines_main = []
self.proj_snap_lines.clear()
self.proj_snap_points.clear()
self.reset_buffers()
self.solv = SolverSystem()
# Example usage
if __name__ == "__main__":
import sys

View File

@@ -30,6 +30,7 @@ class VTKWidget(QtWidgets.QWidget):
self.picked_edge_actors = []
self.displayed_normal_actors = []
self.body_actors_orig = []
self.projected_mesh_actors = []
self.flip_toggle = False
@@ -40,14 +41,34 @@ class VTKWidget(QtWidgets.QWidget):
# Create VTK pipeline
self.renderer = vtk.vtkRenderer()
self.vtk_widget.GetRenderWindow().AddRenderer(self.renderer)
self.interactor = self.vtk_widget.GetRenderWindow().GetInteractor()
self.renderer_projections = vtk.vtkRenderer()
self.renderer_indicators = vtk.vtkRenderer()
# Set up the camera
self.camera = self.renderer.GetActiveCamera()
self.renderer.SetViewport(0, 0, 1, 1) # Full viewport
self.renderer_projections.SetViewport(0, 0, 1, 1) # Full viewport, overlays the first
self.renderer_indicators.SetViewport(0, 0, 1, 1) # Full viewport, overlays the first
self.renderer.SetLayer(0)
self.renderer_projections.SetLayer(1)
self.renderer_indicators.SetLayer(2) # This will be on top
# Add renderers to the render window
render_window = self.vtk_widget.GetRenderWindow()
render_window.SetNumberOfLayers(3)
render_window.AddRenderer(self.renderer)
render_window.AddRenderer(self.renderer_projections)
render_window.AddRenderer(self.renderer_indicators)
# Set up shared camera
self.camera = vtk.vtkCamera()
self.camera.SetPosition(5, 5, 1000)
self.camera.SetFocalPoint(0, 0, 0)
self.camera.SetClippingRange(0.1, 10000)
self.camera.SetClippingRange(0.1, 100000)
self.renderer.SetActiveCamera(self.camera)
self.renderer_projections.SetActiveCamera(self.camera)
self.renderer_indicators.SetActiveCamera(self.camera)
self.interactor = self.vtk_widget.GetRenderWindow().GetInteractor()
# Light Setup
def add_light(renderer, position, color=(1, 1, 1), intensity=1.0):
@@ -65,7 +86,6 @@ class VTKWidget(QtWidgets.QWidget):
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()
self.picker.SetTolerance(0.005)
@@ -120,6 +140,13 @@ class VTKWidget(QtWidgets.QWidget):
self.renderer.AddActor(actor)
def update_render(self):
self.renderer.ResetCameraClippingRange()
self.renderer_projections.ResetCameraClippingRange()
self.renderer_indicators.ResetCameraClippingRange()
self.vtk_widget.GetRenderWindow().Render()
def create_grid(self, size=100, spacing=10):
# Create a vtkPoints object and store the points in it
points = vtk.vtkPoints()
@@ -398,10 +425,10 @@ 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")
def compute_2d_coordinates_line(self, line_source, normal):
# Ensure the input is a vtkLineSource
if not isinstance(line_source, vtk.vtkLineSource):
raise ValueError("Input must be a vtkLineSource")
# Normalize the normal vector
normal = np.array(normal)
@@ -422,19 +449,9 @@ class VTKWidget(QtWidgets.QWidget):
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)
# Get the polydata from the line source
line_source.Update()
polydata = line_source.GetOutput()
# Apply the transform to the polydata
transform_filter = vtk.vtkTransformPolyDataFilter()
@@ -543,6 +560,7 @@ class VTKWidget(QtWidgets.QWidget):
def on_invert_normal(self):
# Kippstufe für Normal flip
if self.selected_normal is not None:
self.clear_actors_normals()
self.compute_projection(self.flip_toggle)
def on_click(self, obj, event):
@@ -563,7 +581,6 @@ 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)
@@ -588,6 +605,8 @@ class VTKWidget(QtWidgets.QWidget):
line_source.SetPoint1(point1)
line_source.SetPoint2(point2)
self.selected_vtk_line.append(line_source)
# Create a mapper and actor for the picked edge
edge_mapper = vtk.vtkPolyDataMapper()
edge_mapper.SetInputConnection(line_source.GetOutputPort())
@@ -595,21 +614,27 @@ 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(8) # Make the line thicker
edge_actor.GetProperty().SetLineWidth(5) # Make the line thicker
# Add the actor to the renderer and store it
self.renderer.AddActor(edge_actor)
self.renderer_indicators.AddActor(edge_actor)
self.picked_edge_actors.append(edge_actor)
if len(self.selected_edges) == 2:
self.compute_projection(False)
if len(self.selected_edges) > 2:
# Clear lists for selection
self.selected_vtk_line.clear()
self.selected_edges.clear()
self.clear_actors_projection()
self.clear_edge_select()
# Clear Actors from view
self.clear_actors_projection()
self.clear_actors_sel_edges()
self.clear_actors_normals()
def find_origin_vertex(self, edge1, edge2):
if edge1[0] == edge2[0]or edge1[0] == edge2[1]:
return edge1[0]
@@ -625,13 +650,18 @@ class VTKWidget(QtWidgets.QWidget):
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 flat_mesh in self.projected_mesh_actors:
self.renderer_projections.RemoveActor(flat_mesh)
def clear_actors_normals(self):
for normals in self.displayed_normal_actors:
self.renderer.RemoveActor(normals)
self.renderer_indicators.RemoveActor(normals)
def compute_projection(self, direction_invert: bool= False):
def clear_actors_sel_edges(self):
for edge_line in self.picked_edge_actors:
self.renderer_indicators.RemoveActor(edge_line)
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]
@@ -662,28 +692,31 @@ class VTKWidget(QtWidgets.QWidget):
self.project_tosketch_points = self.compute_2d_coordinates(projected_polydata, self.selected_normal)
# Seperately rotate selected edges for drawing
self.project_tosketch_lines.clear()
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)
print("outgoing lines", self.project_tosketch_lines)
# Create a mapper and actor for the projected data
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(projected_polydata)
# Projected mesh in green
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(8) # Set line width
actor.GetProperty().SetLineWidth(4) # Set line width
self.renderer.AddActor(normal_actor)
self.renderer_indicators.AddActor(normal_actor)
self.displayed_normal_actors.append(normal_actor)
# Add the edge lines actor to the scene
self.renderer.AddActor(actor)
self.picked_edge_actors.append(actor)
self.renderer_projections.AddActor(actor)
self.projected_mesh_actors.append(actor)
# Render the scene
self.update_render()
self.vtk_widget.GetRenderWindow().Render()
def start(self):