[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