def __init__(self):
     self.IsProcessed = False
     self.Interaction = True
     self.ShowAnnotations = True
     self.ShowDirections = True
     self.AboutDataVisibility = True
     self.LinkRender = True
     self.LinkCameraFocalAndPosition = False
     
     
     self.Renderer = None
     self.RenderWindow = None
     self.RenderWindowInteractor = None
     self.Children = []
     self.InteractorStyle = None
     # Initilize Annotations
     self.CornerAnnotation = vtk.vtkCornerAnnotation()
     self.CornerAnnotation.SetNonlinearFontScaleFactor(0.3)
     
     self.TextProperty = vtk.vtkTextProperty()
     self.CornerAnnotation.SetTextProperty(self.TextProperty)
     
     #self.OrientationAnnotation = vtkOrientationAnnotation()
     #self.OrientationAnnotation.SetNonlinearFontScaleFactor(0.25)
     
     #self.InteractorStyle = vtk.vtkInteractorStyleSwitch()
     
     self.Parent = None
     
     self.downRightAnnotation = ""
     self.upLeftAnnotation = ""
     self.upRightAnnotation = ""
     self.downLeftAnnotation = ""
     self.AboutData = ""
     self.InternalMTime = 0
 def __init__(self):
     '''
     Constructor
     '''
     
     self.__OrientationMatrix = vtk.vtkMatrix4x4()
     self.__CornerAnnotation = vtk.vtkCornerAnnotation()
     self.__TextProperty = vtk.vtkTextProperty()
     self.__LookupTable = vtk.vtkLookupTable()
     self.__ScalarBarActor = vtk.vtkScalarBarActor()
     self.__Prop3DCollection = vtk.vtkProp3DCollection()
     self.__DataSetCollection = vtk.vtkDataSetCollection()
     self.__OrientationTransform = vtk.vtkMatrixToLinearTransform()
     
     self.__OrientationMatrix.Identity()
     self.__CornerAnnotation.SetNonlinearFontScaleFactor(0.30)
     self.__CornerAnnotation.SetText(0, "Jolly - (c) summit 2009 ref vtkINRIA3D")
     self.__CornerAnnotation.SetMaximumFontSize(46)
     
     self.__ScalarBarActor.SetLabelTextProperty(self.__TextProperty)
     
     self.__ScalarBarActor.GetLabelTextProperty().BoldOff()
     self.__ScalarBarActor.GetLabelTextProperty().ItalicOff()
     self.__ScalarBarActor.SetNumberOfLabels(3)
     self.__ScalarBarActor.SetWidth(0.1)
     self.__ScalarBarActor.SetHeight(0.5)
     self.__ScalarBarActor.SetPosition(0.9, 0.3)
     self.__LookupTable.SetTableRange(0, 1)
     self.__LookupTable.SetSaturationRange(0, 0)
     self.__LookupTable.SetHueRange(0, 0)
     self.__LookupTable.SetValueRange(0, 1)
     self.__LookupTable.Build()
     
     self.__ShowAnnotations = True
     self.__ShowScalarBar = True
     
     self.__OrientationTransform.SetInput(self.__OrientationMatrix)
     
     self.__WindowLevel = self.GetWindowLevel()
     self.__WindowLevel.SetLookupTable( self.__LookupTable )
     self.__ScalarBarActor.SetLookupTable(self.__LookupTable)
     
     self.__Renderer = self.GetRenderer()
     self.__Renderer.AddViewProp(self.__CornerAnnotation)
     self.__Renderer.AddViewProp(self.__ScalarBarActor)
     
     self.__ImageActor = self.GetImageActor()
     self.__RenderWindow = self.GetRenderWindow ()
     self.__InteractorStyle = self.GetInteractorStyle()
     self.__Interactor = None
     
     self.__CornerAnnotation.SetWindowLevel(self.__WindowLevel)
     self.__CornerAnnotation.SetImageActor(self.__ImageActor)
     self.__CornerAnnotation.ShowSliceAndImageOn()
     
     # Sometime we would want to set the default window/level value instead
     # of the ImageData's ScalarRange
     self.__RefWindow = None
     self.__RefLevel = None
Пример #3
0
    def make_legend_text_object(self):
        self.legend = vtk.vtkCornerAnnotation()
        self.legend.SetText(0,"Quake Cloud 3d Visualiser\n\
Depth Markers are 25Km Apart\n\
Maximum depth for model: {}\n\
All other distances are relative \n\n\n\
Copyright 2013 Jay Gattuso\n\n".format(self.event_max_depth))
        self.legend.SetMaximumFontSize(15)
Пример #4
0
    def createCornerAnnotation(self):
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetMaximumFontSize(12)
        cornerAnnotation.PickableOff()
        cornerAnnotation.VisibilityOff()
        cornerAnnotation.GetTextProperty().ShadowOn()
        self.GetRenderer().AddActor(cornerAnnotation)

        return cornerAnnotation
Пример #5
0
    def make_legend_text_object(self):
        self.legend = vtk.vtkCornerAnnotation()
        self.legend.SetText(
            0, "Quake Cloud 3d Visualiser\n\
Depth Markers are 25Km Apart\n\
Maximum depth for model: {}\n\
All other distances are relative \n\n\n\
Copyright 2013 Jay Gattuso\n\n".format(self.event_max_depth))
        self.legend.SetMaximumFontSize(15)
Пример #6
0
 def getVtkCornerAnnotation(self,caption= ''):
   self.annotation = vtk.vtkCornerAnnotation()
   self.date= datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
   self.annotation.SetText(self.upperRight, self.date) 
   self.annotation.SetText(self.upperLeft, self.version)
   #vtkCornerAnnotation doesn't seems to support UTF-8 very well.
   caption= su.remove_accents(caption)
   if(len(caption)>self.captionWidth):
     caption= textwrap.fill(caption,self.captionWidth)
   self.annotation.SetText(self.lowerLeft,caption)
   return self.annotation
Пример #7
0
 def getVtkCornerAnnotation(self, caption=''):
     self.annotation = vtk.vtkCornerAnnotation()
     self.date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
     self.annotation.SetText(self.upperRight, self.date)
     self.annotation.SetText(self.upperLeft, self.version)
     #vtkCornerAnnotation doesn't seems to support UTF-8 very well.
     caption = su.remove_accents(caption)
     if (len(caption) > self.captionWidth):
         caption = textwrap.fill(caption, self.captionWidth)
     self.annotation.SetText(self.lowerLeft, caption)
     return self.annotation
Пример #8
0
    def show(self):
        """Displays the mesh in the meshmagick viewer with additional graphics proper to hydrostatics"""
        # TODO: Ce n'est pas ce module qui doit savoir utiliser vtk !!!

        import MMviewer
        import vtk

        vtk_polydata = self.mesh._vtk_polydata()
        self.viewer = MMviewer.MMViewer()
        self.viewer.add_polydata(vtk_polydata)

        pd_orig = self.viewer.add_point([0, 0, 0], color=[0, 0, 0])

        pd_cog = self.viewer.add_point(self.gravity_center, color=[1, 0, 0])

        pd_orig_cog = self.viewer.add_line([0, 0, 0], self.gravity_center, color=[1, 0, 0])

        pd_buoy = self.viewer.add_point(self.buoyancy_center, color=[0, 1, 0])

        pd_orig_buoy = self.viewer.add_line([0, 0, 0], self.buoyancy_center, color=[0, 1, 0])

        scale = self.mass * 1000

        # Adding glyph for gravity force
        gforce = self.get_gravity_force()
        self.viewer.add_vector(gforce.point, gforce.value, scale=scale, color=[1, 0, 0])

        # Adding glyph for buoyancy force
        bforce = self.get_buoyancy_force()
        self.viewer.add_vector(bforce.point, bforce.value, scale=scale, color=[0, 1, 0])

        # Adding glyph for additional forces
        for force in self.additional_forces:
            self.viewer.add_point(force.point, color=[0, 0, 1])
            self.viewer.add_vector(force.point, force.value, scale=scale, color=[0, 0, 1])

        # TODO: mettre la suite dans une methode de MMViewer
        # Adding corner annotation
        ca = vtk.vtkCornerAnnotation()
        ca.SetLinearFontScaleFactor(2)
        ca.SetNonlinearFontScaleFactor(1)
        ca.SetMaximumFontSize(20)
        labels = "Origin: Black; Gravity Center: Red; Buoyancy Center: Green\nTo see points, press 'w'"
        ca.SetText(2, labels)
        ca.GetTextProperty().SetColor(0., 0., 0.)
        self.viewer.renderer.AddViewProp(ca)

        # Showing the viewer
        self.viewer.show()
        self.viewer.finalize()

        return
Пример #9
0
    def plot_point_cloud_qt(self, plot, widget):
        """
        :param plot: the specific VTKPointCloud being plotted
        :param widget: the QVTKRenderWindowInteractor that acts as the container for the specific VTK object

        A function to plot a single VTKPointCloud
        """
        rw = widget.GetRenderWindow()
        iren = widget.GetRenderWindow().GetInteractor()
        # iren.SetRenderWindow(rw)

        ren = vtk.vtkRenderer()
        ren.AddActor(plot.vtkActor)
        self.widget_point_actors.append(plot.vtkActor)
        rw.AddRenderer(ren)
        ren.SetBackground(self.background)

        camera = ren.GetActiveCamera()
        corner = vtk.vtkCornerAnnotation()
        orientation = camera.GetOrientation()
        corner.SetText(
            0, "(x, y, z) = (%.3f, %.3f, %.3f)" %
            (orientation[0], orientation[1], orientation[2]))
        ren.AddActor(corner)
        i = self.widgets.index(widget)
        axes = self.axes_actors[i]
        axes.SetInputConnection(self.plots[i].outline.GetOutputPort())
        axes.SetCamera(camera)
        axes.SetLabelFormat("%6.4g")
        axes.SetFlyModeToOuterEdges()
        axes.SetFontFactor(1.2)
        if self.axes_on:
            ren.AddViewProp(axes)

        ren.ResetCamera()

        iren.SetInteractorStyle(
            CustomInteractorStyle(ren=ren, corner=corner, app=self.app))
        # a picker is used for clicking interactions if you want any cutsom ones
        picker = vtk.vtkPointPicker()
        iren.SetPicker(picker)
        rw.Render()
Пример #10
0
    def SetCornorAnnotations(self):
        # Corner annotation, can use <slice>, <slice_pos>, <window_level>
        self.cornerAnnotation = vtk.vtkCornerAnnotation()
        self.cornerAnnotation.SetLinearFontScaleFactor(2)
        self.cornerAnnotation.SetNonlinearFontScaleFactor(1)
        self.cornerAnnotation.SetMaximumFontSize(20)
        self.cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, {
            2: 'Axial Superior',
            0: 'Sagittal Left',
            1: 'Coronal Anterior'
        }[self.iDim])
        prop = self.cornerAnnotation.GetTextProperty()
        prop.BoldOn()
        color = deque((1, 0, 0))
        color.rotate(self.iDim)
        self.cornerAnnotation.GetTextProperty().SetColor(tuple(color))
        self.cornerAnnotation.SetImageActor(self.viewer.GetImageActor())

        self.cornerAnnotation.SetWindowLevel(self.viewer.GetWindowLevel())
        self.viewer.GetRenderer().AddViewProp(self.cornerAnnotation)
Пример #11
0
    def SetInputData(self, data):
        self.viewer.SetInputData(data)
        # Corner annotation, can use <slice>, <slice_pos>, <window_level>
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetLinearFontScaleFactor(2)
        cornerAnnotation.SetNonlinearFontScaleFactor(1)
        cornerAnnotation.SetMaximumFontSize(20)
        cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, {
            2: 'Axial',
            0: 'Sagittal',
            1: 'Coronal'
        }[self.iDim])
        prop = cornerAnnotation.GetTextProperty()
        prop.BoldOn()
        color = deque((1, 0, 0))
        color.rotate(self.iDim)
        cornerAnnotation.GetTextProperty().SetColor(tuple(color))
        cornerAnnotation.SetImageActor(self.viewer.GetImageActor())

        cornerAnnotation.SetWindowLevel(self.viewer.GetWindowLevel())
        self.viewer.GetRenderer().AddViewProp(cornerAnnotation)
        self.__Reslice.SetOutputSpacing(1.0, 1.0, 1.0)
        self.__Reslice.SetOutputOrigin(0,0,0)
        self.__Reslice.SetOutputExtent(0, int(planeSizeX-1), 0, 
                                       int(planeSizeY-1), 0, 0)
        
        self.__Reslice.Update()
        
    def getMatrix(self):
        return self.__Reslice
    
    def getReslice(self):
        return self.__Reslice


    def getResliceAxes(self):
        return self.__ResliceAxes


    def setReslice(self, value):
        self.__Reslice = value


    def setResliceAxes(self, value):
        self.__ResliceAxes = value

if __name__ == "__main__":
    print vtk.vtkCornerAnnotation().GetActors()[0]
    print vtk.vtkCornerAnnotation().GetActors()[1]
    print vtk.vtkCornerAnnotation().GetActors()[2]
    print vtk.vtkCornerAnnotation().GetActors()[3]
 
Пример #13
0
def text(txt,
         pos=(0, 0, 0),
         normal=(0, 0, 1),
         s=1,
         depth=0.1,
         c='k',
         alpha=1,
         bc=None,
         texture=None,
         followcam=False,
         cam=None):
    '''
    Returns a vtkActor that shows a text in 3D.

    Options:

        pos = position in 3D space,
              if an integer is passed [1 -> 8], places text in one of the 4 corners

        s = size of text 

        depth = text thickness

        followcam = False, if True the text will auto-orient itself to it.

    [**Example1**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/colorcubes.py)    
    [**Example2**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/mesh_coloring.py)    
    '''
    if isinstance(pos, int):
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetNonlinearFontScaleFactor(s / 3)
        cornerAnnotation.SetText(pos - 1, str(txt))
        cornerAnnotation.GetTextProperty().SetColor(colors.getColor(c))
        return cornerAnnotation

    tt = vtk.vtkVectorText()
    tt.SetText(str(txt))
    tt.Update()
    ttmapper = vtk.vtkPolyDataMapper()
    if followcam:
        depth = 0
        normal = (0, 0, 1)
    if depth:
        extrude = vtk.vtkLinearExtrusionFilter()
        extrude.SetInputConnection(tt.GetOutputPort())
        extrude.SetExtrusionTypeToVectorExtrusion()
        extrude.SetVector(0, 0, 1)
        extrude.SetScaleFactor(depth)
        ttmapper.SetInputConnection(extrude.GetOutputPort())
    else:
        ttmapper.SetInputConnection(tt.GetOutputPort())
    if followcam:
        ttactor = vtk.vtkFollower()
        ttactor.SetCamera(cam)
    else:
        ttactor = Actor()
    ttactor.SetMapper(ttmapper)
    ttactor.GetProperty().SetColor(colors.getColor(c))

    # check if color string contains a float, in this case ignore alpha
    al = colors.getAlpha(c)
    if al:
        alpha = al
    ttactor.GetProperty().SetOpacity(alpha)

    nax = np.linalg.norm(normal)
    if nax:
        normal = np.array(normal) / nax
    theta = np.arccos(normal[2])
    phi = np.arctan2(normal[1], normal[0])
    ttactor.SetScale(s, s, s)
    ttactor.RotateZ(phi * 57.3)
    ttactor.RotateY(theta * 57.3)
    ttactor.SetPosition(pos)
    if bc:  # defines a specific color for the backface
        backProp = vtk.vtkProperty()
        backProp.SetDiffuseColor(colors.getColor(bc))
        backProp.SetOpacity(alpha)
        ttactor.SetBackfaceProperty(backProp)
    if texture:
        ttactor.texture(texture)
    return ttactor
Пример #14
0
    def __init__(self):

        self.text_actor = vtk.vtkCornerAnnotation()
Пример #15
0
 def make_timed_text_object(self):
     self.timer_text = vtk.vtkCornerAnnotation()
     self.timer_text.SetMaximumFontSize(20)
Пример #16
0
def text(txt,
         pos=(0, 0, 0),
         normal=(0, 0, 1),
         s=1,
         depth=0.1,
         justify='bottom-left',
         c='k',
         alpha=1,
         bc=None,
         texture=None,
         followcam=False,
         cam=None):
    '''
    Returns a ``vtkActor`` that shows a 3D text.

    :param pos: position in 3D space, 
                if an integer is passed [1,8], place text in one of the 4 corners.
    :type pos: list, int
    :param float s: size of text.
    :param float depth: text thickness.
    :param str justify: text justification (bottom-left, bottom-right, top-left, top-right, centered).
    :param bool followcam: if `True` the text will auto-orient itself to the cam.

    .. hint:: Example: `colorcubes.py <https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/colorcubes.py>`_
    
        .. image:: https://user-images.githubusercontent.com/32848391/50738867-c0658e80-11d8-11e9-9e05-ac69b546b7ec.png
    '''
    if isinstance(pos, int):
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetNonlinearFontScaleFactor(s / 3)
        cornerAnnotation.SetText(pos - 1, str(txt))
        cornerAnnotation.GetTextProperty().SetColor(colors.getColor(c))
        return cornerAnnotation

    tt = vtk.vtkVectorText()
    tt.SetText(str(txt))
    tt.Update()
    ttmapper = vtk.vtkPolyDataMapper()
    if followcam:
        depth = 0
        normal = (0, 0, 1)
    if depth:
        extrude = vtk.vtkLinearExtrusionFilter()
        extrude.SetInputConnection(tt.GetOutputPort())
        extrude.SetExtrusionTypeToVectorExtrusion()
        extrude.SetVector(0, 0, 1)
        extrude.SetScaleFactor(depth)
        ttmapper.SetInputConnection(extrude.GetOutputPort())
    else:
        ttmapper.SetInputConnection(tt.GetOutputPort())
    if followcam:
        ttactor = vtk.vtkFollower()
        ttactor.SetCamera(cam)
    else:
        ttactor = Actor()
    ttactor.SetMapper(ttmapper)
    ttactor.GetProperty().SetColor(colors.getColor(c))
    ttmapper.Update()

    bb = tt.GetOutput().GetBounds()
    dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s
    cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2,
                   (bb[5] + bb[4]) / 2]) * s
    shift = -cm
    if 'cent' in justify:
        pass
    elif 'bottom-left' in justify:
        shift += np.array([dx, dy, 0])
    elif 'top-left' in justify:
        shift += np.array([dx, -dy, 0])
    elif 'bottom-right' in justify:
        shift += np.array([-dx, dy, 0])
    elif 'top-right' in justify:
        shift += np.array([-dx, -dy, 0])
    else:
        colors.printc("text(): Unknown justify type", justify, c=1)

    # check if color string contains a float, in this case ignore alpha
    al = colors._getAlpha(c)
    if al:
        alpha = al
    ttactor.GetProperty().SetOpacity(alpha)

    nax = np.linalg.norm(normal)
    if nax:
        normal = np.array(normal) / nax
    theta = np.arccos(normal[2])
    phi = np.arctan2(normal[1], normal[0])
    ttactor.SetScale(s, s, s)
    ttactor.RotateZ(phi * 57.3)
    ttactor.RotateY(theta * 57.3)
    ttactor.SetPosition(pos + shift)
    if bc:  # defines a specific color for the backface
        backProp = vtk.vtkProperty()
        backProp.SetDiffuseColor(colors.getColor(bc))
        backProp.SetOpacity(alpha)
        ttactor.SetBackfaceProperty(backProp)
    if texture:
        ttactor.texture(texture)
    ttactor.PickableOff()
    return ttactor
Пример #17
0
def Text(
    txt,
    pos=3,
    s=1,
    depth=0.1,
    justify="bottom-left",
    c=None,
    alpha=1,
    bc=None,
    bg=None,
    font="courier",
    followcam=False,
):
    """
    Returns an ``Actor`` that shows a 2D/3D text.

    :param pos: position in 3D space,
                if an integer is passed [1,8],
                a 2D text is placed in one of the 4 corners:

                    1, bottom-left
                    2, bottom-right
                    3, top-left
                    4, top-right
                    5, bottom-middle
                    6, middle-right
                    7, middle-left
                    8, top-middle

                If a pair (x,y) is passed as input the 2D text is place at that
                position in the coordinate system of the 2D screen (with the
                origin sitting at the bottom left).

    :type pos: list, int
    :param float s: size of text.
    :param float depth: text thickness.
    :param str justify: text justification
        (bottom-left, bottom-right, top-left, top-right, centered).
    :param bg: background color of corner annotations. Only applies of `pos` is ``int``.
    :param str font: additional available fonts are:

            - Ageo
            - Aldora
            - CallingCode
            - Godsway
            - Gula
            - ImpactLabel
            - Komiko
            - Lamborgini
            - MidnightDrive
            - Militech
            - MonaShark
            - Montserrat
            - MyDisplaySt
            - PointedLaidSt
            - SchoolTeacher
            - SpecialElite

        Font choice does not apply for 3D text.
        A path to `otf` or `ttf` font-file can also be supplied as input.

        All fonts are free for personal use.
        Check out conditions in `vtkplotter/fonts/licenses` for commercial use
        and: https://www.1001freefonts.com

    :param followcam: if `True` the text will auto-orient itself to the active camera.
        A ``vtkCamera`` object can also be passed.
    :type followcam: bool, vtkCamera

    .. hint:: Examples, |fonts.py|_ |colorcubes.py|_ |markpoint.py|_ |annotations.py|_

        |colorcubes| |markpoint|

        |fonts|
    """
    if c is None: # automatic black or white
        if settings.plotter_instance and settings.plotter_instance.renderer:
            c = (0.9, 0.9, 0.9)
            if np.sum(settings.plotter_instance.renderer.GetBackground()) > 1.5:
                c = (0.1, 0.1, 0.1)
        else:
            c = (0.6, 0.6, 0.6)

    if isinstance(pos, int): # corners
        if pos > 8:
            pos = 8
        if pos < 1:
            pos = 1
        ca = vtk.vtkCornerAnnotation()
        ca.SetNonlinearFontScaleFactor(s/2.7)
        ca.SetText(pos - 1, str(txt))
        ca.PickableOff()
        cap = ca.GetTextProperty()
        cap.SetColor(colors.getColor(c))
        if font.lower() == "courier": cap.SetFontFamilyToCourier()
        elif font.lower() == "times": cap.SetFontFamilyToTimes()
        elif font.lower() == "arial": cap.SetFontFamilyToArial()
        else:
            cap.SetFontFamily(vtk.VTK_FONT_FILE)
            cap.SetFontFile(settings.fonts_path+font+'.ttf')
        if bg:
            bgcol = colors.getColor(bg)
            cap.SetBackgroundColor(bgcol)
            cap.SetBackgroundOpacity(alpha * 0.5)
            cap.SetFrameColor(bgcol)
            cap.FrameOn()
        setattr(ca, 'renderedAt', set())
        settings.collectable_actors.append(ca)
        return ca

    elif len(pos)==2: # passing (x,y) coords
        actor2d = vtk.vtkActor2D()
        actor2d.SetPosition(pos)
        tmapper = vtk.vtkTextMapper()
        actor2d.SetMapper(tmapper)
        tp = tmapper.GetTextProperty()
        tp.BoldOff()
        tp.SetFontSize(s*20)
        tp.SetColor(colors.getColor(c))
        tp.SetJustificationToLeft()
        tp.SetVerticalJustificationToBottom()
        if font.lower() == "courier": tp.SetFontFamilyToCourier()
        elif font.lower() == "times": tp.SetFontFamilyToTimes()
        elif font.lower() == "arial": tp.SetFontFamilyToArial()
        else:
            tp.SetFontFamily(vtk.VTK_FONT_FILE)
            import os
            if font in settings.fonts:
                tp.SetFontFile(settings.fonts_path + font + '.ttf')
            elif os.path.exists(font):
                tp.SetFontFile(font)
            else:
                colors.printc("~sad Font", font, "not found in", settings.fonts_path, c="r")
                colors.printc("~pin Available fonts are:", settings.fonts, c="m")
                return None
        if bg:
            bgcol = colors.getColor(bg)
            tp.SetBackgroundColor(bgcol)
            tp.SetBackgroundOpacity(alpha * 0.5)
            tp.SetFrameColor(bgcol)
            tp.FrameOn()
        tmapper.SetInput(str(txt))
        actor2d.PickableOff()
        setattr(actor2d, 'renderedAt', set())
        settings.collectable_actors.append(actor2d)
        return actor2d

    else:
        # otherwise build the 3D text, fonts do not apply
        tt = vtk.vtkVectorText()
        tt.SetText(str(txt))
        tt.Update()
        tpoly = tt.GetOutput()

        bb = tpoly.GetBounds()
        dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s
        cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2, (bb[5] + bb[4]) / 2]) * s
        shift = -cm
        if "bottom" in justify: shift += np.array([  0, dy, 0])
        if "top"    in justify: shift += np.array([  0,-dy, 0])
        if "left"   in justify: shift += np.array([ dx,  0, 0])
        if "right"  in justify: shift += np.array([-dx,  0, 0])

        t = vtk.vtkTransform()
        t.Translate(shift)
        t.Scale(s, s, s)
        tf = vtk.vtkTransformPolyDataFilter()
        tf.SetInputData(tpoly)
        tf.SetTransform(t)
        tf.Update()
        tpoly = tf.GetOutput()

        if followcam:
            ttactor = vtk.vtkFollower()
            ttactor.GetProperty().SetOpacity(alpha)
            ttactor.GetProperty().SetColor(colors.getColor(c))
            if isinstance(followcam, vtk.vtkCamera):
                ttactor.SetCamera(followcam)
            else:
                ttactor.SetCamera(settings.plotter_instance.camera)
        else:
            if depth:
                extrude = vtk.vtkLinearExtrusionFilter()
                extrude.SetInputData(tpoly)
                extrude.SetExtrusionTypeToVectorExtrusion()
                extrude.SetVector(0, 0, 1)
                extrude.SetScaleFactor(depth*dy)
                extrude.Update()
                tpoly = extrude.GetOutput()
            ttactor = Actor(tpoly, c, alpha, bc=bc)

        ttactor.SetPosition(pos)
        settings.collectable_actors.append(ttactor)
        return ttactor
def text(txt,
         pos=(0, 0, 0),
         normal=(0, 0, 1),
         s=1,
         depth=0.1,
         c='k',
         alpha=1,
         bc=None,
         texture=None,
         followcam=False,
         cam=None):
    '''
    Returns a vtkActor that shows a text in 3D.
        
        pos = position in 3D space
              if an integer is passed [1 -> 8], places text in a corner
        s = size of text 
        depth = text thickness
        followcam = True, the text will auto-orient itself to it
    '''
    if isinstance(pos, int):
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetNonlinearFontScaleFactor(s / 3)
        cornerAnnotation.SetText(pos - 1, txt)
        cornerAnnotation.GetTextProperty().SetColor(vc.getColor(c))
        return cornerAnnotation

    tt = vtk.vtkVectorText()
    tt.SetText(txt)
    tt.Update()
    ttmapper = vtk.vtkPolyDataMapper()
    if depth:
        extrude = vtk.vtkLinearExtrusionFilter()
        extrude.SetInputConnection(tt.GetOutputPort())
        extrude.SetExtrusionTypeToVectorExtrusion()
        extrude.SetVector(0, 0, 1)
        extrude.SetScaleFactor(depth)
        ttmapper.SetInputConnection(extrude.GetOutputPort())
    else:
        ttmapper.SetInputConnection(tt.GetOutputPort())
    if followcam:  #follow cam
        ttactor = vtk.vtkFollower()
        ttactor.SetCamera(cam)
    else:
        ttactor = vtk.vtkActor()
    ttactor.SetMapper(ttmapper)
    ttactor.GetProperty().SetColor(vc.getColor(c))

    # check if color string contains a float, in this case ignore alpha
    al = vc.getAlpha(c)
    if al: alpha = al
    ttactor.GetProperty().SetOpacity(alpha)

    nax = np.linalg.norm(normal)
    if nax: normal = np.array(normal) / nax
    theta = np.arccos(normal[2])
    phi = np.arctan2(normal[1], normal[0])
    ttactor.SetScale(s, s, s)
    ttactor.RotateZ(phi * 57.3)
    ttactor.RotateY(theta * 57.3)
    ttactor.SetPosition(pos)
    if bc:  # defines a specific color for the backface
        backProp = vtk.vtkProperty()
        backProp.SetDiffuseColor(vc.getColor(bc))
        backProp.SetOpacity(alpha)
        ttactor.SetBackfaceProperty(backProp)
    if texture: vu.assignTexture(ttactor, texture)
    vu.assignConvenienceMethods(ttactor, None)
    vu.assignPhysicsMethods(ttactor)
    return ttactor
Пример #19
0
    def setup(self):
        self.setupUi(self)

        loadAct = QAction('&Open', self)
        loadAct.setShortcut('Ctrl+O')
        loadAct.setStatusTip('Load data')
        loadAct.triggered.connect(lambda: self.onLoadClicked(0))

        surfAct = QAction('&Open Surface', self)
        surfAct.setShortcut('Ctrl+S')
        surfAct.setStatusTip('Surf data')
        surfAct.triggered.connect(lambda: self.onLoadClicked(1))

        exitAct = QAction('&Exit', self)
        exitAct.setShortcut('ALT+F4')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(self.close)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(loadAct)
        fileMenu.addAction(surfAct)
        fileMenu.addAction(exitAct)

        self.vtk_widgets = [
            Viewer2D(self.vtk_panel, 0),
            Viewer2D(self.vtk_panel, 1),
            Viewer2D(self.vtk_panel, 2)
        ]

        # Make all views share the same cursor object
        for i in range(3):
            self.vtk_widgets[i].viewer.SetResliceCursor(
                self.vtk_widgets[0].viewer.GetResliceCursor())

        # Cursor representation (anti-alias)
        for i in range(3):
            for j in range(3):
                prop = self.vtk_widgets[i].viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)

        # Make 3D viewer
        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)

        ipwProp = vtk.vtkProperty()
        ren = vtk.vtkRenderer()
        interactor = QVTKRenderWindowInteractor()

        # Gradient background
        ren.SetBackground(245.0 / 255.0, 245.0 / 255.0, 245.0 / 255.0)
        ren.SetBackground2(170.0 / 255.0, 170.0 / 255.0, 170.0 / 255.0)
        ren.GradientBackgroundOn()

        interactor.GetRenderWindow().AddRenderer(ren)
        self.vtk_widgets.append(interactor)

        # Create plane widgets
        self.planeWidget = []
        for i in range(3):
            pw = vtk.vtkImagePlaneWidget()
            pw.SetInteractor(interactor)
            pw.SetPicker(picker)
            pw.RestrictPlaneToVolumeOn()
            color = [0.0, 0.0, 0.0]
            color[i] = 1
            pw.GetPlaneProperty().SetColor(color)
            pw.SetTexturePlaneProperty(ipwProp)
            pw.TextureInterpolateOn()
            pw.SetResliceInterpolateToLinear()
            pw.DisplayTextOn()
            pw.SetDefaultRenderer(ren)

            prop = pw.GetPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetPlaneProperty(prop)

            prop = pw.GetSelectedPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetSelectedPlaneProperty(prop)

            prop = pw.GetCursorProperty()
            renderLinesAsTubes(prop)
            pw.SetCursorProperty(prop)

            prop = pw.GetTextProperty()
            prop.SetColor(black)

            pw.Modified()
            # Set background for 2D views
            for j in range(3):
                color[j] = color[j] / 4.0
            self.vtk_widgets[i].viewer.GetRenderer().SetBackground(color)
            self.vtk_widgets[i].interactor.Disable()
            self.planeWidget.append(pw)

        # Annotation
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetLinearFontScaleFactor(2)
        cornerAnnotation.SetNonlinearFontScaleFactor(1)
        cornerAnnotation.SetMaximumFontSize(20)
        cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, '3D')
        cornerAnnotation.GetTextProperty().SetColor(1, 1, 1)
        cornerAnnotation.SetWindowLevel(
            self.vtk_widgets[0].viewer.GetWindowLevel())
        ren.AddViewProp(cornerAnnotation)

        # Create cube, Right Anterior Superior
        colors = vtk.vtkNamedColors()
        xyzLabels = ['X', 'Y', 'Z']
        scale = (1.5, 1.5, 1.5)
        axes2 = MakeCubeActor(scale, xyzLabels, colors)
        self.om2 = vtk.vtkOrientationMarkerWidget()
        self.om2.SetOrientationMarker(axes2)
        # Position lower right in the viewport.
        self.om2.SetInteractor(self.vtk_widgets[3])
        self.om2.SetViewport(0.75, 0, 1.0, 0.25)

        self.establishCallbacks()

        # Show widgets but hide non-existing data
        for i in range(3):
            self.vtk_widgets[i].show()
            self.vtk_widgets[i].viewer.GetImageActor().SetVisibility(False)

        # Layouts
        horz_layout0 = QHBoxLayout()
        vert_splitter = QSplitter(Qt.Vertical)
        horz_splitter0 = QSplitter(Qt.Horizontal)
        horz_splitter0.addWidget(self.vtk_widgets[0])
        horz_splitter0.addWidget(self.vtk_widgets[1])
        vert_splitter.addWidget(horz_splitter0)
        horz_splitter1 = QSplitter(Qt.Horizontal)
        horz_splitter1.addWidget(self.vtk_widgets[2])
        horz_splitter1.addWidget(self.vtk_widgets[3])
        vert_splitter.addWidget(horz_splitter1)
        horz_layout0.addWidget(vert_splitter)
        horz_layout0.setContentsMargins(0, 0, 0, 0)
        self.vtk_panel.setLayout(horz_layout0)

        vert_layout = QVBoxLayout()
        horz_layout1 = QHBoxLayout()
        self.btnSagittal = QPushButton("S")
        self.btnSagittal.setCheckable(True)
        self.btnSagittal.setChecked(True)
        horz_layout1.addWidget(self.btnSagittal)
        self.btnCoronal = QPushButton("C")
        self.btnCoronal.setCheckable(True)
        self.btnCoronal.setChecked(True)
        horz_layout1.addWidget(self.btnCoronal)
        self.btnAxial = QPushButton("A")
        self.btnAxial.setCheckable(True)
        self.btnAxial.setChecked(True)

        self.btnSagittal.clicked.connect(self.togglePlanes)
        self.btnCoronal.clicked.connect(self.togglePlanes)
        self.btnAxial.clicked.connect(self.togglePlanes)

        horz_layout1.addWidget(self.btnAxial)
        verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        vert_layout.addItem(verticalSpacer)
        vert_layout.addItem(horz_layout1)
        self.frame.setLayout(vert_layout)
Пример #20
0
    def __init__(self):

        # Building renderer
        self.renderer = vtk.vtkRenderer()
        self.renderer.SetBackground(0.7706, 0.8165, 1.0)

        # Building render window
        self.render_window = vtk.vtkRenderWindow()
        # self.render_window.FullScreenOn() # BUGFIX: It causes the window to fail to open...
        self.render_window.SetSize(1024, 768)
        self.render_window.SetWindowName("Meshmagick viewer")
        self.render_window.AddRenderer(self.renderer)

        # Building interactor
        self.render_window_interactor = vtk.vtkRenderWindowInteractor()
        self.render_window_interactor.SetRenderWindow(self.render_window)
        self.render_window_interactor.GetInteractorStyle(
        ).SetCurrentStyleToTrackballCamera()
        self.render_window_interactor.AddObserver('KeyPressEvent',
                                                  self.on_key_press, 0.0)

        # Building axes view
        axes = vtk.vtkAxesActor()
        widget = vtk.vtkOrientationMarkerWidget()
        widget.SetOrientationMarker(axes)
        self.widget = widget

        self.widget.SetInteractor(self.render_window_interactor)
        self.widget.SetEnabled(1)
        self.widget.InteractiveOn()

        # Building command annotations
        command_text = "left mouse : rotate\n" + \
                       "right mouse : zoom\n" + \
                       "middle mouse : pan\n" + \
                       "ctrl+left mouse : spin\n" + \
                       "n : (un)show normals\n" + \
                       "b : (un)show axes box\n" + \
                       "f : focus on the mouse cursor\n" + \
                       "r : reset view\n" + \
                       "s : surface representation\n" + \
                       "w : wire representation\n" + \
                       "h : (un)show Oxy plane\n" + \
                       "g : (un)show Axes planes\n" + \
                       "x : save\n" + \
                       "c : screenshot\n" + \
                       "q : quit"

        corner_annotation = vtk.vtkCornerAnnotation()
        corner_annotation.SetLinearFontScaleFactor(2)
        corner_annotation.SetNonlinearFontScaleFactor(1)
        corner_annotation.SetMaximumFontSize(20)
        corner_annotation.SetText(3, command_text)
        corner_annotation.GetTextProperty().SetColor(0., 0., 0.)
        self.renderer.AddViewProp(corner_annotation)

        copyright_text = "Meshmagick Viewer\nCopyright 2014-%u, Ecole Centrale de Nantes" % __year__

        copyright_annotation = vtk.vtkCornerAnnotation()
        copyright_annotation.SetLinearFontScaleFactor(1)
        copyright_annotation.SetNonlinearFontScaleFactor(1)
        copyright_annotation.SetMaximumFontSize(12)
        copyright_annotation.SetText(1, copyright_text)
        copyright_annotation.GetTextProperty().SetColor(0., 0., 0.)
        self.renderer.AddViewProp(copyright_annotation)

        self.normals = []
        self.axes = []
        self.oxy_plane = None
        self.axes_planes = None

        self.polydatas = list()
        self.hiden = dict()  # TODO: A terminer -> cf methode self.hide()
Пример #21
0
def main(argv):
    imageViewer = vtk.vtkImageViewer2()
    if len(argv) < 2:
        noiseSource = vtk.vtkImageNoiseSource()
        noiseSource.SetWholeExtent(0, 512, 0, 512, 0, 0)
        noiseSource.SetMinimum(0.0)
        noiseSource.SetMaximum(65535.0)

        # cast noise image to unsigned short
        imageCast = vtk.vtkImageCast()
        imageCast.SetInputConnection(noiseSource.GetOutputPort())
        imageCast.SetOutputScalarTypeToUnsignedShort()
        imageCast.Update()
        # connect to image viewer pipeline
        imageViewer.SetInputConnection(imageCast.GetOutputPort())
    else:
        # Parse input argument
        inputFilename = str(argv[1])

        # Read the image
        tiffReader = vtk.vtkTIFFReader()
        if not tiffReader.CanReadFile(inputFilename):
            return
        tiffReader.SetFileName(inputFilename)

        # connect to image viewer pipeline
        imageViewer.SetInputConnection(tiffReader.GetOutputPort())

    # Picker to pick pixels
    propPicker = vtk.vtkPropPicker()
    propPicker.PickFromListOn()

    # Give the picker a prop to pick
    imageActor = imageViewer.GetImageActor()
    propPicker.AddPickList(imageActor)

    # disable interpolation, so we can see each pixel
    imageActor.InterpolateOff()

    # Visualize
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    imageViewer.SetupInteractor(renderWindowInteractor)
    imageViewer.SetSize(600, 600)

    renderer = imageViewer.GetRenderer()
    renderer.ResetCamera()
    renderer.GradientBackgroundOn()
    renderer.SetBackground(0.6, 0.6, 0.5)
    renderer.SetBackground2(0.3, 0.3, 0.2)

    # Annotate the image with window/level and mouse over pixel
    # information
    cornerAnnotation = vtk.vtkCornerAnnotation()
    cornerAnnotation.SetLinearFontScaleFactor(2)
    cornerAnnotation.SetNonlinearFontScaleFactor(1)
    cornerAnnotation.SetMaximumFontSize(20)
    cornerAnnotation.SetText(0, "Off Image")
    cornerAnnotation.SetText(3, "<window>\n<level>")
    cornerAnnotation.GetTextProperty().SetColor(1, 0, 0)

    imageViewer.GetRenderer().AddViewProp(cornerAnnotation)

    # Callback listens to MouseMoveEvents invoked by the interactor's style
    callback = vtkImageInteractionCallback()
    callback.SetViewer(imageViewer)
    callback.SetAnnotation(cornerAnnotation)
    callback.SetPicker(propPicker)

    # InteractorStyleImage allows for the following controls:
    # 1) middle mouse + move = camera pan
    # 2) left mouse + move = window/level
    # 3) right mouse + move = camera zoom
    # 4) middle mouse wheel scroll = zoom
    # 5) 'r' = reset window/level
    # 6) shift + 'r' = reset camera
    imageStyle = imageViewer.GetInteractorStyle()
    imageStyle.AddObserver('MouseMoveEvent', callback.Execute)

    if len(argv) > 1:
        imageViewer.GetImageActor().GetMapper().SetInputConnection(
            tiffReader.GetOutputPort())

    renderWindowInteractor.Initialize()
    renderWindowInteractor.Start()
Пример #22
0
 def make_timed_text_object(self):
     self.timer_text = vtk.vtkCornerAnnotation()
     self.timer_text.SetMaximumFontSize(20)
Пример #23
0
    def __init__(self,
                 world_to_slice,
                 layers=None,
                 annotations=None,
                 interpolation=False,
                 display_coordinates="physical",
                 scalar_bar_visibility=False,
                 orientation_visibility=True,
                 corner_annotations_visibility=False,
                 crosshair="full"):

        layers = layers or []
        annotations = annotations or ObservableList()

        ############################
        # Property-related members #
        ############################

        self._interpolation = None
        self._display_coordinates = None
        self._scalar_bar_visibility = True
        self._orientation_visibility = None
        self._corner_annotations_visibility = None
        self._crosshair = None

        self._world_to_slice = None

        self._slice_to_world = None

        self._layers = []

        self._annotations = None
        self._gui_annotations = {}

        self._image_physical_position = None
        self._image_index_position = None

        self._cursor_physical_position = None
        self._cursor_index_position = None

        self._zoom = None

        self._mouse_tools = {}
        self._keyboard_tools = {}

        self._renderer = vtkRenderer()

        ###################
        # Private members #
        ###################

        # World-to-slice matrix, with rows and columns added or removed so that
        # it is 3x3.
        self._3d_world_to_slice = None
        self._3d_slice_to_world = None

        # Slice extent is the physical extent of all layers,
        # given as (x_min, x_max, y_min, y_max)
        self._slice_extent = (-100, 100, -100, 100)

        # VTK objects
        self._scalar_bar_actor = vtkScalarBarActor()
        self._corner_annotation = vtkCornerAnnotation()
        self._orientation_annotation = vtkOrientationAnnotation()
        self._crosshair = Crosshair()

        # Tools and interactions
        self._observer_tags = []
        self._active_source = None

        ##################
        # Initialization #
        ##################

        super(Slice, self).__init__([
            "world_to_slice", "interpolation", "display_coordinates",
            "scalar_bar_visibility", "orientation_visibility",
            "corner_annotations_visibility", "crosshair", "zoom"
        ])
        self.add_allowed_event("cursor_position")
        self.add_allowed_event("image_position")
        self.add_allowed_event("center")
        self.add_allowed_event("layer_visibility")

        # Configure camera
        camera = self._renderer.GetActiveCamera()
        camera.ParallelProjectionOn()
        camera.SetPosition(0, 0, self._actors_altitudes["camera"])
        camera.SetFocalPoint(0, 0, 0)

        # Create cursor
        self._crosshair.altitude = self._actors_altitudes["cursor"]
        self._crosshair.hole_size = 5
        self._renderer.AddActor(self._crosshair.actor)

        # Create scalar bar (from vtkInria3D)
        self._scalar_bar_actor.GetLabelTextProperty().SetColor(1.0, 1.0, 1.0)
        self._scalar_bar_actor.GetTitleTextProperty().SetColor(1.0, 1.0, 1.0)
        self._scalar_bar_actor.GetLabelTextProperty().BoldOff()
        self._scalar_bar_actor.GetLabelTextProperty().ShadowOff()
        self._scalar_bar_actor.GetLabelTextProperty().ItalicOff()
        self._scalar_bar_actor.SetNumberOfLabels(3)
        self._scalar_bar_actor.GetLabelTextProperty().SetFontSize(8)
        self._scalar_bar_actor.GetPositionCoordinate(
        ).SetCoordinateSystemToNormalizedViewport()
        self._scalar_bar_actor.SetWidth(0.1)
        self._scalar_bar_actor.SetHeight(0.5)
        self._scalar_bar_actor.SetPosition(0.8, 0.3)
        self._scalar_bar_actor.PickableOff()
        self._renderer.AddActor(self._scalar_bar_actor)

        # Setup text-annotation actors
        self._corner_annotation.SetNonlinearFontScaleFactor(0.3)
        self._renderer.AddActor(self._corner_annotation)
        self._orientation_annotation.SetNonlinearFontScaleFactor(0.25)
        self._renderer.AddActor(self._orientation_annotation)

        self._set_interpolation(interpolation)
        self._set_display_coordinates(display_coordinates)

        self._set_scalar_bar_visibility(scalar_bar_visibility)
        self._set_orientation_visibility(orientation_visibility)
        self._set_corner_annotations_visibility(corner_annotations_visibility)
        self._set_crosshair(crosshair)

        self._set_world_to_slice(world_to_slice)

        for layer in layers:
            self.append_layer(**layer)

        if annotations is not None:
            self._set_annotations(annotations)

        # Position slice at middle of layer 0
        self.reset_view()

        # Configure default tools
        self.set_mouse_button_tool("Left", mouse_tools.Select())
        self.set_mouse_button_tool("Middle", mouse_tools.Pan())
        self.set_mouse_button_tool("Right", mouse_tools.WindowLevel())
        self.set_wheel_tool("Forward", mouse_tools.Zoom(1.1))
        self.set_wheel_tool("Backward", mouse_tools.Zoom(1. / 1.1))
        self.set_keyboard_tool("Left", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("Right", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("Up", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("Down", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("Prior", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("Next", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("PageUp", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("PageDown", keyboard_tools.MoveCursor())
        self.set_keyboard_tool("+", keyboard_tools.Zoom(1.1))
        self.set_keyboard_tool("-", keyboard_tools.Zoom(1. / 1.1))
        self.set_keyboard_tool("i", keyboard_tools.ToggleInterpolation())
        self.set_keyboard_tool("b", keyboard_tools.ToggleScalarBarVisibility())
        self.set_keyboard_tool(
            "c", keyboard_tools.ToggleCornerAnnotationsVisibility())
        self.set_keyboard_tool("o",
                               keyboard_tools.ToggleOrientationVisibility())
Пример #24
0
def main():
    session = Set_Render_Variables("quake(13).csv")

    data = Data_Extractor(session)
    bounds = Model_Bounds_Points_Maker(data, session)
    events = Timed_Event_List_Maker(data.event_list, session)

    # sets up the VTK session
    ren = vtk.vtkRenderer()
    renderWindow = vtk.vtkRenderWindow()
    #renderWindow.AddRenderer(ren)
    i_ren = vtk.vtkRenderWindowInteractor()
    i_ren.SetRenderWindow(renderWindow)

    # text / legend object
    legend = vtk.vtkCornerAnnotation()
    legend.SetText(0, "          Quake Cloud 3d Visualiser\n          Depth Markers are 25Km Apart\n"
                      "          All other distances are relative \n\n\n          Copyright 2013 Jay Gattuso\n\n")
    legend.SetMaximumFontSize(15)


    # handles the overlay map image
    input_image = session.overlay_image_fname
    reader = vtk.vtkJPEGReader()
    reader.SetFileName(input_image)
    texture = vtk.vtkTexture()
    texture.SetInput(reader.GetOutput())
    texture.SetInputConnection(reader.GetOutputPort())
    texture.InterpolateOn()

    ren = vtk.vtkRenderer()
    renderWindow.AddRenderer(ren)
    plane = vtk.vtkPlaneSource()
    plane.SetOrigin((0, 0, 0))
    plane.SetPoint1(bounds.lat_max_distance)
    plane.SetPoint2(bounds.long_max_distance)

    # Create texture object
    planeMapper = vtk.vtkPolyDataMapper()
    planeMapper.SetInputConnection(plane.GetOutputPort())
    planeActor = vtk.vtkActor()
    planeActor.SetMapper(planeMapper)
    planeActor.SetTexture(texture)

    pointCloud_bounds = VtkPointCloud(data.event_max_depth)

    if session.plot_boundary_markers:
        for bound in bounds.bounds:
            pointCloud_bounds.addPoint(bound, 10)  # the number is what makes the bound markers larger

    if session.plot_depth_scale:
        for bound in bounds.bounds_scale:
            pointCloud_bounds.addPoint(bound, 10)  # the number is what makes the bound markers larger

    # add basic objects (bounds, overlay, background)
    ren.AddActor(pointCloud_bounds.vtkActor)
    ren.AddViewProp(legend)
    ren.AddActor(planeActor)
    ren.SetBackground(.2, .2, .2)
    ren.ResetCamera()

    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)

    # Begin Interaction
    renderWindow.Render()

    # Initialize must be called prior to creating timer events.
    renderWindowInteractor.Initialize()

    # Sign up to receive TimerEvent
    cb = vtkTimerCallback(events.timed_event_dict, data.event_max_depth, ren, renderWindow, session)
    cb.actor = vtk.vtkActor()
    renderWindowInteractor.AddObserver('TimerEvent', cb.execute)
    timerId = renderWindowInteractor.CreateRepeatingTimer(session.replay_frame_speed)

    renderWindowInteractor.Start()
Пример #25
0
    def setup(self):
        self.setupUi(self)

        loadAct = QAction('&Open', self)
        loadAct.setShortcut('Ctrl+O')
        loadAct.setStatusTip('Load data')
        loadAct.triggered.connect(lambda: self.onLoadClicked(0))

        surfAct = QAction('&Open Surface', self)
        surfAct.setShortcut('Ctrl+S')
        surfAct.setStatusTip('Surf data')
        surfAct.triggered.connect(lambda: self.onLoadClicked(1))

        exitAct = QAction('&Exit', self)
        exitAct.setShortcut('ALT+F4')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(self.close)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(loadAct)
        fileMenu.addAction(surfAct)
        fileMenu.addAction(exitAct)

        self.vtk_widgets = [
            Viewer2D(self.vtk_panel, 0),
            Viewer2D(self.vtk_panel, 1),
            Viewer2D(self.vtk_panel, 2)
        ]

        # Make all views share the same cursor object
        for i in range(3):
            self.vtk_widgets[i].viewer.SetResliceCursor(
                self.vtk_widgets[0].viewer.GetResliceCursor())

        # Cursor representation (anti-alias)
        for i in range(3):
            for j in range(3):
                prop = self.vtk_widgets[i].viewer.GetResliceCursorWidget(
                ).GetResliceCursorRepresentation().GetResliceCursorActor(
                ).GetCenterlineProperty(j)
                renderLinesAsTubes(prop)

        # Make 3D viewer
        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)

        ipwProp = vtk.vtkProperty()
        ren = vtk.vtkRenderer()
        interactor = QVTKRenderWindowInteractor()

        # Gradient background
        ren.SetBackground(245.0 / 255.0, 245.0 / 255.0, 245.0 / 255.0)
        ren.SetBackground2(170.0 / 255.0, 170.0 / 255.0, 170.0 / 255.0)
        ren.GradientBackgroundOn()

        interactor.GetRenderWindow().AddRenderer(ren)
        self.vtk_widgets.append(interactor)

        # Create plane widgets
        self.planeWidget = []
        for i in range(3):
            pw = vtk.vtkImagePlaneWidget()
            pw.SetInteractor(interactor)
            pw.SetPicker(picker)
            pw.RestrictPlaneToVolumeOn()
            color = [0.0, 0.0, 0.0]
            color[i] = 1
            pw.GetPlaneProperty().SetColor(color)
            pw.SetTexturePlaneProperty(ipwProp)
            pw.TextureInterpolateOn()
            pw.SetResliceInterpolateToLinear()
            pw.DisplayTextOn()
            pw.SetDefaultRenderer(ren)

            prop = pw.GetPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetPlaneProperty(prop)

            prop = pw.GetSelectedPlaneProperty()
            renderLinesAsTubes(prop)
            pw.SetSelectedPlaneProperty(prop)

            prop = pw.GetCursorProperty()
            renderLinesAsTubes(prop)
            pw.SetCursorProperty(prop)

            prop = pw.GetTextProperty()
            prop.SetColor(black)
            pw.Modified()
            # Set background for 2D views
            for j in range(3):
                color[j] = color[j] / 4.0
            self.vtk_widgets[i].viewer.GetRenderer().SetBackground(color)
            self.vtk_widgets[i].interactor.Disable()
            self.planeWidget.append(pw)

        # Annotation
        cornerAnnotation = vtk.vtkCornerAnnotation()
        cornerAnnotation.SetLinearFontScaleFactor(2)
        cornerAnnotation.SetNonlinearFontScaleFactor(1)
        cornerAnnotation.SetMaximumFontSize(20)
        cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, '3D')
        cornerAnnotation.GetTextProperty().SetColor(1, 1, 1)
        cornerAnnotation.SetWindowLevel(
            self.vtk_widgets[0].viewer.GetWindowLevel())
        ren.AddViewProp(cornerAnnotation)

        self.establishCallbacks()

        # Show widgets but hide non-existing data
        for i in range(3):
            self.vtk_widgets[i].show()
            self.vtk_widgets[i].viewer.GetImageActor().SetVisibility(False)

        # Layouts
        horz_layout0 = QHBoxLayout()
        vert_splitter = QSplitter(Qt.Vertical)
        horz_splitter0 = QSplitter(Qt.Horizontal)
        horz_splitter0.addWidget(self.vtk_widgets[0])
        horz_splitter0.addWidget(self.vtk_widgets[1])
        vert_splitter.addWidget(horz_splitter0)
        horz_splitter1 = QSplitter(Qt.Horizontal)
        horz_splitter1.addWidget(self.vtk_widgets[2])
        horz_splitter1.addWidget(self.vtk_widgets[3])
        vert_splitter.addWidget(horz_splitter1)
        horz_layout0.addWidget(vert_splitter)
        horz_layout0.setContentsMargins(0, 0, 0, 0)
        self.vtk_panel.setLayout(horz_layout0)

        vert_layout = QVBoxLayout()

        # Sagittal/Coronal/Axial planes - not used
        horz_layout1 = QHBoxLayout()
        self.btnSagittal = QPushButton("S")
        self.btnSagittal.setCheckable(True)
        self.btnSagittal.setChecked(True)
        horz_layout1.addWidget(self.btnSagittal)
        self.btnCoronal = QPushButton("C")
        self.btnCoronal.setCheckable(True)
        self.btnCoronal.setChecked(True)
        horz_layout1.addWidget(self.btnCoronal)
        self.btnAxial = QPushButton("A")
        self.btnAxial.setCheckable(True)
        self.btnAxial.setChecked(True)
        horz_layout1.addWidget(self.btnAxial)

        self.btnSagittal.clicked.connect(self.togglePlanes)
        self.btnCoronal.clicked.connect(self.togglePlanes)
        self.btnAxial.clicked.connect(self.togglePlanes)

        verticalSpacer = QSpacerItem(10, 10, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        vert_layout.addSpacerItem(verticalSpacer)

        # Misalignment
        groupBox = QGroupBox("Misalignment")
        vert_layout.addWidget(groupBox)
        mis_layout = QVBoxLayout()

        # Local and reset
        horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.btnLocal = QCheckBox("local")
        self.btnReset = QPushButton("Reset")
        self.btnReset.clicked.connect(self.onResetOffset)

        # Misalignment buttons
        horz_layout4 = QHBoxLayout()
        horz_layout4.addWidget(self.btnLocal)
        horz_layout4.addSpacerItem(horzSpacer)
        horz_layout4.addWidget(self.btnReset)
        mis_layout.addItem(horz_layout4)

        # Misalignment sliders
        [(self.sliderTX, self.btnTransX), (self.sliderTY, self.btnTransY),
         (self.sliderTZ, self.btnTransZ), (self.sliderRX, self.btnRotX),
         (self.sliderRY, self.btnRotY), (self.sliderRZ, self.btnRotZ)
         ] = self.createMisAlignment(mis_layout, self.onOrientationClicked)
        groupBox.setLayout(mis_layout)

        # Movement
        groupBox = QGroupBox("Movement")
        vert_layout.addWidget(groupBox)
        groupLayout = QVBoxLayout()

        # Local and reset
        horzSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)

        # TODO: Return values
        self.btnMoveLocal = QCheckBox("local")
        self.btnReset1 = QPushButton("Reset")
        self.btnReset1.clicked.connect(self.onResetMovement)

        # Movement sliders
        layout = QHBoxLayout()
        layout.addWidget(self.btnMoveLocal)
        layout.addSpacerItem(horzSpacer)
        layout.addWidget(self.btnReset1)
        groupLayout.addItem(layout)

        [
            (self.sliderMTX, self.sliderMTY, self.sliderMTZ),
            (self.sliderMRX, self.sliderMRY, self.sliderMRZ)
        ] = self.createMovement(groupLayout, self.onSliderPressed, self.onMove)
        groupBox.setLayout(groupLayout)

        self.frame.setLayout(vert_layout)
Пример #26
0
    def loadFile(self, fileName):
        # Load VTK Meta Image
        reader = vtk.vtkMetaImageReader()
        reader.SetFileName(fileName)
        reader.Update()
        imageDims = reader.GetOutput().GetDimensions()

        # Disable renderers and widgets
        for i in range(3):
            self.vtk_widgets[i].viewer.GetInteractor().EnableRenderOff()
        self.vtk_widgets[3].EnableRenderOff()

        # Turn-off plane widgets
        for i in range(3):
            self.planeWidget[i].Off()

        # Assign data to 2D viewers sharing one cursorobject
        for i in range(3):
            self.vtk_widgets[i].viewer.SetInputData(reader.GetOutput())

        # Corner annotation
        for i in range(3):
            # TODO: Use (<slice>, <slice_pos>, <window_level>). WindowLevel not signaled when changed in RIW's
            cornerAnnotation = vtk.vtkCornerAnnotation()
            cornerAnnotation.SetLinearFontScaleFactor(2)
            cornerAnnotation.SetNonlinearFontScaleFactor(1)
            cornerAnnotation.SetMaximumFontSize(20)
            cornerAnnotation.SetText(vtk.vtkCornerAnnotation.UpperLeft, {
                2: 'Axial',
                0: 'Sagittal',
                1: 'Coronal'
            }[i])
            cornerAnnotation.GetTextProperty().SetColor(1, 1, 1)
            cornerAnnotation.SetImageActor(
                self.vtk_widgets[i].viewer.GetImageActor())

            cornerAnnotation.SetWindowLevel(
                self.vtk_widgets[0].viewer.GetWindowLevel())
            self.vtk_widgets[i].viewer.GetRenderer().AddViewProp(
                cornerAnnotation)  # Issue

        # Enable plane widgets
        for i in range(3):
            self.planeWidget[i].SetInputConnection(reader.GetOutputPort())
            self.planeWidget[i].SetPlaneOrientation(i)
            self.planeWidget[i].SetSliceIndex(imageDims[i] // 2)
            self.planeWidget[i].GetInteractor().Enable()
            self.planeWidget[i].On()
            self.planeWidget[i].InteractionOn()

        # Enable 2D viewers
        for i in range(3):
            self.vtk_widgets[i].viewer.GetRenderer().ResetCamera()
            self.vtk_widgets[i].viewer.GetInteractor().EnableRenderOn()

        # Enable interactors
        for i in range(3):
            self.vtk_widgets[i].interactor.Enable()
            self.vtk_widgets[i].viewer.GetInteractor().Enable()

        # Enable 3D rendering
        self.vtk_widgets[3].EnableRenderOn()
        # Reset camera for the renderer - otherwise it is set using dummy data
        self.planeWidget[0].GetDefaultRenderer().ResetCamera()

        # Update 3D
        self.ResetViews()
        self.SetResliceMode(1)
Пример #27
0
            def doReslice(renWin, reader, viewNr, orientation, level, window):

                # Calculate the center of the volume
                reader.Update()
                (xMin, xMax, yMin, yMax, zMin,
                 zMax) = reader.GetExecutive().GetWholeExtent(
                     reader.GetOutputInformation(0))
                (xSpacing, ySpacing,
                 zSpacing) = reader.GetOutput().GetSpacing()
                (x0, y0, z0) = reader.GetOutput().GetOrigin()

                center = [
                    x0 + xSpacing * 0.5 * (xMin + xMax),
                    y0 + ySpacing * 0.5 * (yMin + yMax),
                    z0 + zSpacing * 0.5 * (zMin + zMax)
                ]

                # Matrices for axial, coronal, sagittal, oblique view orientations
                axial = vtk.vtkMatrix4x4()
                axial.DeepCopy((1, 0, 0, center[0], 0, 1, 0, center[1], 0, 0,
                                1, center[2], 0, 0, 0, 1))

                coronal = vtk.vtkMatrix4x4()
                coronal.DeepCopy((1, 0, 0, center[0], 0, 0, 1, center[1], 0,
                                  -1, 0, center[2], 0, 0, 0, 1))

                sagittal = vtk.vtkMatrix4x4()
                sagittal.DeepCopy((0, 0, -1, center[0], 1, 0, 0, center[1], 0,
                                   -1, 0, center[2], 0, 0, 0, 1))

                # Extract a slice in the desired orientation
                reslice = vtk.vtkImageReslice()
                reslice.SetInputConnection(reader.GetOutputPort())
                reslice.SetOutputDimensionality(2)
                reslice.SetResliceAxes(axial)
                if orientation == "coronal":
                    reslice.SetResliceAxes(coronal)
                if orientation == "sagittal":
                    reslice.SetResliceAxes(sagittal)
                reslice.SetInterpolationModeToLinear()

                range1 = int(level) - int(window) / 2
                range2 = int(level) + int(window) / 2

                # Create a greyscale lookup table
                table = vtk.vtkLookupTable()
                table.SetRange(range1, range2)  # image intensity range
                table.SetValueRange(0.0, 1.0)  # from black to white
                table.SetSaturationRange(0.0, 0.0)  # no color saturation
                table.SetRampToLinear()
                table.Build()

                # Map the image through the lookup table
                color = vtk.vtkImageMapToColors()
                color.SetLookupTable(table)
                color.SetInputConnection(reslice.GetOutputPort())

                # Display the image
                actor = vtk.vtkImageActor()
                actor.GetMapper().SetInputConnection(color.GetOutputPort())

                cornerAnnotation = vtk.vtkCornerAnnotation()
                cornerAnnotation.SetLinearFontScaleFactor(1)
                cornerAnnotation.SetNonlinearFontScaleFactor(1)
                cornerAnnotation.SetMinimumFontSize(12)
                cornerAnnotation.SetMaximumFontSize(20)
                cornerAnnotation.SetText(0, "lower left")
                cornerAnnotation.SetText(1, "lower right")
                cornerAnnotation.SetText(2, "upper left")
                cornerAnnotation.SetText(3, "upper right")
                cornerAnnotation.GetTextProperty().SetColor(1, 1, 1)

                ren = vtk.vtkRenderer()
                ren.SetBackground(0.0, 0.0, 0.0)
                ren.AddActor(actor)
                #ren.AddViewProp( cornerAnnotation )
                ren.SetViewport(*getViewport(viewNr))
                renWin.AddRenderer(ren)
                ren.ResetCamera()

                camera = ren.GetActiveCamera()
                camera.Zoom(1.4)

                ViewportBorder(ren, [1, 1, 1], False)

                return reslice
Пример #28
0
def Text(
    txt,
    pos=3,
    normal=(0, 0, 1),
    s=1,
    depth=0.1,
    justify="bottom-left",
    c=None,
    alpha=1,
    bc=None,
    bg=None,
    font="courier",
    followcam=False,
):
    """
    Returns a ``vtkActor`` that shows a 3D text.

    :param pos: position in 3D space,
                if an integer is passed [1,8],
                a 2D text is placed in one of the 4 corners:

                    1, bottom-left
                    2, bottom-right
                    3, top-left
                    4, top-right
                    5, bottom-middle
                    6, middle-right
                    7, middle-left
                    8, top-middle

    :type pos: list, int
    :param float s: size of text.
    :param float depth: text thickness.
    :param str justify: text justification
        (bottom-left, bottom-right, top-left, top-right, centered).
    :param bg: background color of corner annotations. Only applies of `pos` is ``int``.
    :param str font: either `arial`, `courier` or `times`. Only applies of `pos` is ``int``.
    :param followcam: if `True` the text will auto-orient itself to the active camera.
        A ``vtkCamera`` object can also be passed.
    :type followcam: bool, vtkCamera

    .. hint:: |colorcubes.py|_ |markpoint.py|_ |annotations.py|_

        |colorcubes| |markpoint|
    """
    if c is None:  # automatic black or white
        if settings.plotter_instance and settings.plotter_instance.renderer:
            c = (0.9, 0.9, 0.9)
            if np.sum(
                    settings.plotter_instance.renderer.GetBackground()) > 1.5:
                c = (0.1, 0.1, 0.1)
        else:
            c = (0.6, 0.6, 0.6)

    if isinstance(pos, int):
        if pos > 8:
            pos = 8
        if pos < 1:
            pos = 1

        ca = vtk.vtkCornerAnnotation()
        ca.SetNonlinearFontScaleFactor(s / 2.7)
        ca.SetText(pos - 1, str(txt))

        ca.PickableOff()
        cap = ca.GetTextProperty()
        cap.SetColor(colors.getColor(c))
        if font.lower() == "courier":
            cap.SetFontFamilyToCourier()
        elif font.lower() == "times":
            cap.SetFontFamilyToTimes()
        else:
            cap.SetFontFamilyToArial()
        if bg:
            bgcol = colors.getColor(bg)
            cap.SetBackgroundColor(bgcol)
            cap.SetBackgroundOpacity(alpha * 0.5)
            cap.SetFrameColor(bgcol)
            cap.FrameOn()

        setattr(ca, 'renderedAt', set())
        settings.collectable_actors.append(ca)
        return ca

    tt = vtk.vtkVectorText()
    tt.SetText(str(txt))
    tt.Update()
    ttmapper = vtk.vtkPolyDataMapper()
    if followcam:
        depth = 0
        normal = (0, 0, 1)
    if depth:
        extrude = vtk.vtkLinearExtrusionFilter()
        extrude.SetInputConnection(tt.GetOutputPort())
        extrude.SetExtrusionTypeToVectorExtrusion()
        extrude.SetVector(0, 0, 1)
        extrude.SetScaleFactor(depth)
        ttmapper.SetInputConnection(extrude.GetOutputPort())
    else:
        ttmapper.SetInputConnection(tt.GetOutputPort())
    if followcam:
        ttactor = vtk.vtkFollower()
        if isinstance(followcam, vtk.vtkCamera):
            ttactor.SetCamera(followcam)
        else:
            ttactor.SetCamera(settings.plotter_instance.camera)
    else:
        ttactor = Actor()
    ttactor.SetMapper(ttmapper)
    ttactor.GetProperty().SetColor(colors.getColor(c))
    ttmapper.Update()

    bb = tt.GetOutput().GetBounds()
    dx, dy = (bb[1] - bb[0]) / 2 * s, (bb[3] - bb[2]) / 2 * s
    cm = np.array([(bb[1] + bb[0]) / 2, (bb[3] + bb[2]) / 2,
                   (bb[5] + bb[4]) / 2]) * s
    shift = -cm
    if "cent" in justify:
        pass
    elif "bottom-left" in justify:
        shift += np.array([dx, dy, 0])
    elif "top-left" in justify:
        shift += np.array([dx, -dy, 0])
    elif "bottom-right" in justify:
        shift += np.array([-dx, dy, 0])
    elif "top-right" in justify:
        shift += np.array([-dx, -dy, 0])
    else:
        colors.printc("~lightning Text(): Unknown justify type", justify, c=1)

    ttactor.GetProperty().SetOpacity(alpha)

    nax = np.linalg.norm(normal)
    if nax:
        normal = np.array(normal) / nax
    theta = np.arccos(normal[2])
    phi = np.arctan2(normal[1], normal[0])
    ttactor.SetScale(s, s, s)
    ttactor.RotateZ(np.rad2deg(phi))
    ttactor.RotateY(np.rad2deg(theta))
    ttactor.SetPosition(pos + shift)
    if bc:  # defines a specific color for the backface
        backProp = vtk.vtkProperty()
        backProp.SetDiffuseColor(colors.getColor(bc))
        backProp.SetOpacity(alpha)
        ttactor.SetBackfaceProperty(backProp)
    ttactor.PickableOff()
    settings.collectable_actors.append(ttactor)
    return ttactor
Пример #29
0
    def __init__(self,
                 parent,
                 slice_mode="multiplanar",
                 layers=None,
                 annotations=None,
                 interpolation=False,
                 display_coordinates="physical",
                 scalar_bar_visibility=False,
                 orientation_visibility=True,
                 corner_annotations_visibility=False,
                 convention="radiological",
                 crosshair="full",
                 *args,
                 **kwargs):

        if annotations is None:
            annotations = ObservableList()

        ##############
        # Properties #
        ##############

        self._slice_mode = None

        self._interpolation = None
        self._display_coordinates = None
        self._scalar_bar_visibility = None
        self._orientation_visibility = None
        self._convention = None
        self._crosshair = None
        self._corner_annotations_visibility = None

        self._annotations = None

        self._cursor_physical_position = None
        self._cursor_index_position = None

        self._center_physical_position = None
        self._center_index_position = None

        self._zoom = None
        self._mouse_tools = {}
        self._keyboard_tools = {}

        ###################
        # Private members #
        ###################
        self._rwi = None
        self._layers = ObservableList()
        self._slices = []
        self._slices_names = []
        self._informations_renderer = vtkRenderer()
        self._informations_renderer.SetViewport(
            *self._viewport["informations"])

        self._informations_corner_annotation = vtkCornerAnnotation()
        self._informations_corner_annotation.SetNonlinearFontScaleFactor(0.3)
        self._informations_renderer.AddActor(
            self._informations_corner_annotation)

        ##################
        # Initialization #
        ##################

        wx.Panel.__init__(self, parent, *args, **kwargs)
        # Explicitely pass size to RWI to propagate it correctly
        self._rwi = wxVTKRenderWindowInteractor(self,
                                                wx.ID_ANY,
                                                size=self.GetSize())
        self._rwi.Enable(1)
        sizer = wx.BoxSizer()
        sizer.Add(self._rwi, 1, wx.EXPAND | wx.ALL, 3)
        self.SetSizer(sizer)
        self._rwi.Bind(wx.EVT_LEFT_DOWN, self._on_button_down)
        self._rwi.Bind(wx.EVT_MIDDLE_DOWN, self._on_button_down)
        self._rwi.Bind(wx.EVT_RIGHT_DOWN, self._on_button_down)
        self._rwi.Bind(wx.EVT_MOUSEWHEEL, self._on_button_down)
        self.Bind(wx.EVT_CLOSE, self._on_close)

        PropertySynchronized.__init__(self, [
            "interpolation", "display_coordinates", "scalar_bar_visibility",
            "orientation_visibility", "zoom"
        ])
        self.add_allowed_event("cursor_position")
        self.add_allowed_event("image_position")
        self.add_allowed_event("center")
        self.add_allowed_event("layer_visibility")
        for event in [
                "data", "display_range", "cut_low", "cut_high",
                "zero_transparency"
        ]:
            self.add_allowed_event("colormap_{0}".format(event))
#        self.add_allowed_event("layer_modified")
#        self.add_allowed_event("activated")

        self._set_interpolation(interpolation)
        self._set_display_coordinates(display_coordinates)
        self._set_scalar_bar_visibility(scalar_bar_visibility)
        self._set_orientation_visibility(orientation_visibility)
        self._set_convention(convention)
        self._set_crosshair(crosshair)
        self._set_corner_annotations_visibility(corner_annotations_visibility)
        for layer in layers or []:
            self.append_layer(**layer)
        self._set_slice_mode(slice_mode)

        self._set_annotations(annotations)

        # Position image at middle of layer 0
        self.reset_view()