[vtkusers] A question asked again!!! Please help!!!
John Hunter
jdhunter at ace.bsd.uchicago.edu
Mon Apr 12 09:15:03 EDT 2004
>>>>> "Yang" == Yang Wang <dietpaopao at netscape.net> writes:
Yang> Dear Tcl/vtk Users, Can anyone give me some hint or help on
Yang> the following problem?
Yang> ______________________________
Yang> 1 ______________________________ 2 | 3 | 4
Yang> __________|________|____________
Yang> This is the interface in the same toplevel window. 1--- for
Yang> 3D volume data 2,3,4--- for slices from x,y,z axias
Yang> orientation respectively in 2D
Yang> Currently, I use vtkVolume16Reader and vtkImagePlaneWidget
Yang> so that I can display in section 1 the 3 slices from x,y,z
Yang> axias orientation that probing the volume in 3D mode. Also 3
Yang> scales that can control each slice index that are shown.
Yang> BUT how can I display the 3 slices respectively again in
Yang> section 2,3,4 which exactly correspond to those in section
Yang> 1, and in 2D mode? Can I still use vtkImagePlaneWidget?
Yang> How can I implement multiple render windows (1,2,3,4) in
Yang> this same top level window?
I do exactly this with a plane wodget observer class. I have 3 IPWs
in one render window which I interact with in 3D, and also each IPW in
3 separate render windows. Changes to the plane widget in one window
are reflected in the other, and vice-versa.
Here a are a few code snippets - the class does a lot more so I am
hesitant to post the whole thing. The planeWidget in the constructor
is the plane widget in the 3D window - the plane widget observer is in
the 2D window
In set_image_data, the observer registers to follow interaction events
with the IPW in the3D window. This is the function
interaction_event. In that function, all the relevant params of the
3D IPW are applied to the observer.
You can ignore all the stuff about ring actors....
class PlaneWidgetObserver(MarkerWindowInteractor):
def __init__(self, planeWidget, owner, orientation, imageData=None):
MarkerWindowInteractor.__init__(self)
self.interactButtons = (1,2,3)
self.pw = planeWidget
self.owner = owner
self.orientation = orientation
self.observer = vtk.vtkImagePlaneWidget()
self.camera = self.renderer.GetActiveCamera()
self.ringActors = vtk.vtkActorCollection()
self.defaultRingLine = 1
self.textActors = {}
self.hasData = 0
self.set_image_data(imageData)
self.lastTime = 0
self.set_mouse1_to_move()
def set_image_data(self, imageData):
if imageData is None: return
self.imageData = imageData
if not self.hasData:
self.pw.AddObserver('InteractionEvent', self.interaction_event)
self.connect("scroll_event", self.scroll_widget_slice)
self.hasData = 1
# make cursor invisible
self.observer.GetCursorProperty().SetOpacity(0.0)
self.observer.TextureInterpolateOn()
self.observer.TextureInterpolateOn()
self.observer.SetKeyPressActivationValue(
self.pw.GetKeyPressActivationValue())
self.observer.GetPlaneProperty().SetColor(0,0,0)
self.observer.SetResliceInterpolate(
self.pw.GetResliceInterpolate())
self.observer.SetLookupTable(self.pw.GetLookupTable())
self.observer.DisplayTextOn()
#self.observer.GetMarginProperty().EdgeVisibilityOff() # turn off edges??
self.observer.SetInput(imageData)
self.observer.SetInteractor(self.interactor)
self.observer.On()
self.observer.InteractionOff()
self.update_plane()
if self.orientation==0: up = (0,0,1)
elif self.orientation==1: up = (0,0,1)
elif self.orientation==2: up = (0,-1,0)
else:
raise ValueError, 'orientation must be in 0,1,2'
center = self.observer.GetCenter()
normal = self.pw.GetNormal()
spacing =imageData.GetSpacing()
bounds = imageData.GetBounds()
offset = max(bounds)
pos = (center[0] + normal[0]*offset,
center[1] - normal[1]*offset,
center[2] - normal[2]*offset)
self.set_camera((center, pos, up))
self.resetCamera = (center, pos, up)
#self.sliceIncrement = spacing[self.orientation]
self.sliceIncrement = 0.1
def scroll_depth(self, step):
# step along the normal
p1 = array(self.pw.GetPoint1())
p2 = array(self.pw.GetPoint2())
origin = self.pw.GetOrigin()
normal = self.pw.GetNormal()
newPlane = vtk.vtkPlane()
newPlane.SetNormal(normal)
newPlane.SetOrigin(origin)
newPlane.Push(step)
newOrigin = newPlane.GetOrigin()
delta = array(newOrigin) - array(origin)
p1 += delta
p2 += delta
self.pw.SetPoint1(p1)
self.pw.SetPoint2(p2)
self.pw.SetOrigin(newOrigin)
self.pw.UpdatePlacement()
self.update_plane()
def scroll_axis1(self, step):
#rotate around axis 1
axis1 = [0,0,0]
self.pw.GetVector1(axis1)
transform = vtk.vtkTransform()
axis2 = [0,0,0]
self.pw.GetVector2(axis2)
transform = vtk.vtkTransform()
transform.RotateWXYZ(step,
(axis1[0] + 0.5*axis2[0],
axis1[1] + 0.5*axis2[2],
axis1[2] + 0.5*axis2[2]))
o, p1, p2 = self.get_plane_points()
o = transform.TransformPoint(o)
p1 = transform.TransformPoint(p1)
p2 = transform.TransformPoint(p2)
self.set_plane_points((o, p1, p2))
self.update_plane()
def scroll_axis2(self, step):
axis1 = [0,0,0]
self.pw.GetVector2(axis1)
transform = vtk.vtkTransform()
axis2 = [0,0,0]
self.pw.GetVector1(axis2)
transform = vtk.vtkTransform()
transform.RotateWXYZ(step,
(axis1[0] + 0.5*axis2[0],
axis1[1] + 0.5*axis2[2],
axis1[2] + 0.5*axis2[2]))
o, p1, p2 = self.get_plane_points()
o = transform.TransformPoint(o)
p1 = transform.TransformPoint(p1)
p2 = transform.TransformPoint(p2)
self.set_plane_points((o, p1, p2))
self.update_plane()
def scroll_widget_slice(self, widget, event):
now = time.time()
elapsed = now - self.lastTime
if elapsed < 0.001: return # swallow repeatede events
if event.direction == gdk.SCROLL_UP: step = 1
elif event.direction == gdk.SCROLL_DOWN: step = -1
if self.interactor.GetShiftKey():
self.scroll_axis1(step)
elif self.interactor.GetControlKey():
self.scroll_axis2(step)
else:
self.scroll_depth(step*self.sliceIncrement)
self.get_pwxyz().Render()
self.update_rings()
self.Render()
self.lastTime = time.time()
def interaction_event(self, *args):
self.update_plane()
self.Render()
def update_plane(self):
p1 = self.pw.GetPoint1()
p2 = self.pw.GetPoint2()
o = self.pw.GetOrigin()
self.observer.SetPoint1(p1)
self.observer.SetPoint2(p2)
self.observer.SetOrigin(o)
self.observer.UpdatePlacement()
self.renderer.ResetCameraClippingRange()
More information about the vtkusers
mailing list