Reputation: 51
I'm pretty new to VTK. I'm trying to use VTK in python to edit a .stl
file using the vtkBoxWidget
. I'm reading the .stl
file, editing it with the vtkBoxWidget
by using the mouse/drag in the window interactor and in the end I want to write the new data to a new .stl
when hitting a certain key.
Here's a code to demonstrate the issue:
#!/usr/bin/env python
import vtk
import sys
import os
filename = "file.stl"
# render the data
reader = vtk.vtkSTLReader()
reader.SetFileName(filename)
stlMapper = vtk.vtkPolyDataMapper()
stlMapper.SetInputConnection(reader.GetOutputPort())
# create an actor for our scene
stlActor = vtk.vtkActor()
stlActor.SetMapper(stlMapper)
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# The box widget observes the events invoked by the render window
# interactor. These events come from user interaction in the render
# window.
boxWidget = vtk.vtkBoxWidget()
boxWidget.SetInteractor(iren)
boxWidget.SetPlaceFactor(1.25)
# Add the actors to the renderer, set the background and window size.
ren.AddActor(stlActor)
ren.SetBackground(0.1, 0.2, 0.4)
renWin.SetSize(300, 300)
# As the box widget is interacted with, it produces a transformation
# matrix that is set on the actor.
t = vtk.vtkTransform()
def TransformActor(obj, event):
global t, stlActor
obj.GetTransform(t)
stlActor.SetUserTransform(t)
def onKeyPressEvent(self, renderer):
key = self.GetKeyCode()
if(key=='l'):
print stlActor.GetBounds()
if(os.path.isfile("done.stl")==1):
os.remove("done.stl")
print stlActor.GetMapper().GetInput().GetBounds()
stlPolyData = stlActor.GetMapper().GetInput()
writer = vtk.vtkSTLWriter()
writer.SetFileName("done.stl")
writer.AddInputDataObject(stlPolyData)
writer.Write()
# Place the interactor initially. The actor is used to place and scale
# the interactor. An observer is added to the box widget to watch for
# interaction events. This event is captured and used to set the
# transformation matrix of the actor.
boxWidget.SetProp3D(stlActor)
boxWidget.PlaceWidget()
boxWidget.AddObserver("InteractionEvent", TransformActor)
iren.AddObserver('KeyPressEvent', onKeyPressEvent)
iren.Initialize()
renWin.Render()
iren.Start()
The problem is that I have no idea how to update the vtkPolyData
or pass the transformations I applied to vtkActor
to the vtkPolyData
. In the code above, I tested this with the .GetBounds() in the two print functions. Originally the object had Bounds:
(-2.0, 2.0, 0.0, 1.625, -1.5, 1.8125)
After updating, the actor Bounds changed, but I can't pass all those properties to the vtkPolyData.
(-2.1331110248939638, 2.246371570191821, -1.5743578447908013, 2.5817210301577385, -2.1311284932847796, 2.0695034726591715)
(-2.0, 2.0, 0.0, 1.625, -1.5, 1.8125)
Thanks!
Upvotes: 1
Views: 3893
Reputation: 51
I think I figured it:
def transformPolyData(actor):
polyData = vtk.vtkPolyData()
polyData.DeepCopy(actor.GetMapper().GetInput())
transform = vtk.vtkTransform()
transform.SetMatrix(actor.GetMatrix())
fil = vtk.vtkTransformPolyDataFilter()
fil.SetTransform(transform)
fil.SetInputDataObject(polyData)
fil.Update()
polyData.DeepCopy(fil.GetOutput())
return polyData;
That will transform the polyData to what I needed before saving.
Upvotes: 3