예제 #1
0
    def addScalarBar(
        self,
        pos=(0.8, 0.05),
        title="",
        titleXOffset=0,
        titleYOffset=15,
        titleFontSize=12,
        nlabels=None,
        c=None,
        horizontal=False,
        useAlpha=True,
    ):
        """
        Add a 2D scalar bar for the specified obj.

        .. hint:: |mesh_coloring| |mesh_coloring.py|_ |scalarbars.py|_
        """
        import vtkplotter.addons as addons
        self.scalarbar = addons.addScalarBar(
            self,
            pos,
            title,
            titleXOffset,
            titleYOffset,
            titleFontSize,
            nlabels,
            c,
            horizontal,
            useAlpha,
        )
        return self
예제 #2
0
def buttonfunc():
    global cmap
    bu.switch()
    cmap = bu.status()
    for mesh in visibles:
        if mesh:
            mesh.pointColors(cmap=cmap)
    vp.renderer.RemoveActor(mesh.scalarbar)
    mesh.scalarbar = addons.addScalarBar(mesh,
                                         pos=(0.04, 0.0),
                                         horizontal=True,
                                         titleFontSize=0)
    vp.renderer.AddActor(mesh.scalarbar)
예제 #3
0
파일: plotter.py 프로젝트: ifve/vtkplotter
    def addScalarBar(self,
                     actor=None,
                     c=None,
                     title="",
                     horizontal=False,
                     vmin=None,
                     vmax=None):
        """Add a 2D scalar bar for the specified actor.

        If `actor` is ``None`` will add it to the last actor in ``self.actors``.

        .. hint:: |mesh_bands| |mesh_bands.py|_
        """
        return addons.addScalarBar(actor, c, title, horizontal, vmin, vmax)
예제 #4
0
 def buttonfunc():
     global _cmap_slicer
     bu.switch()
     _cmap_slicer = bu.status()
     for mesh in visibles:
         if mesh:
             mesh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
             if map2cells:
                 mesh.mapPointsToCells()
     vp.renderer.RemoveActor(mesh.scalarbar)
     mesh.scalarbar = addScalarBar(mesh,
                                   pos=(0.04, 0.0),
                                   horizontal=True,
                                   titleFontSize=0)
     vp.renderer.AddActor(mesh.scalarbar)
예제 #5
0
파일: plotter.py 프로젝트: ifve/vtkplotter
    def show(
        self, *actors, **options
        #        at=None,
        #        axes=None,
        #        c=None,
        #        alpha=None,
        #        wire=False,
        #        bc=None,
        #        resetcam=True,
        #        zoom=False,
        #        interactive=None,
        #        rate=None,
        #        viewup="",
        #        azimuth=0,
        #        elevation=0,
        #        roll=0,
        #        interactorStyle=0,
        #        q=False,
    ):
        """
        Render a list of actors.

        Allowed input objects are: ``filename``, ``vtkPolyData``, ``vtkActor``,
        ``vtkActor2D``, ``vtkImageActor``, ``vtkAssembly`` or ``vtkVolume``.

        If filename is given, its type is guessed based on its extension.
        Supported formats are:
        `vtu, vts, vtp, ply, obj, stl, 3ds, xml, neutral, gmsh, pcd, xyz, txt, byu,
        tif, slc, vti, mhd, png, jpg`.

        :param int at: number of the renderer to plot to, if more than one exists
        :param int axes: set the type of axes to be shown

              - 0,  no axes,
              - 1,  draw three gray grid walls
              - 2,  show cartesian axes from (0,0,0)
              - 3,  show positive range of cartesian axes from (0,0,0)
              - 4,  show a triad at bottom left
              - 5,  show a cube at bottom left
              - 6,  mark the corners of the bounding box
              - 7,  draw a simple ruler at the bottom of the window
              - 8,  show the ``vtkCubeAxesActor`` object,
              - 9,  show the bounding box outLine,
              - 10, show three circles representing the maximum bounding box

        :param c:     surface color, in rgb, hex or name formats
        :param bc:    set a color for the internal surface face
        :param bool wire:  show actor in wireframe representation
        :param float azimuth/elevation/roll:  move camera accordingly
        :param str viewup:  either ['x', 'y', 'z'] or a vector to set vertical direction
        :param bool resetcam:  re-adjust camera position to fit objects
        :param bool interactive:  pause and interact with window (True)
            or continue execution (False)
        :param float rate:  maximum rate of `show()` in Hertz
        :param int interactorStyle: set the type of interaction

            - 0, TrackballCamera
            - 1, TrackballActor
            - 2, JoystickCamera
            - 3, Unicam
            - 4, Flight
            - 5, RubberBand3D
            - 6, RubberBandZoom

        :param bool q:  force program to quit after `show()` command returns.
        """
        if not hasattr(self, 'window'):
            return

        at = options.pop("at", None)
        axes = options.pop("axes", None)
        c = options.pop("c", None)
        alpha = options.pop("alpha", None)
        wire = options.pop("wire", False)
        bc = options.pop("bc", None)
        resetcam = options.pop("resetcam", True)
        zoom = options.pop("zoom", False)
        interactive = options.pop("interactive", None)
        rate = options.pop("rate", None)
        viewup = options.pop("viewup", "")
        azimuth = options.pop("azimuth", 0)
        elevation = options.pop("elevation", 0)
        roll = options.pop("roll", 0)
        interactorStyle = options.pop("interactorStyle", 0)
        q = options.pop("q", False)

        if self.offscreen:
            interactive = False
            self.interactive = False

        def scan(wannabeacts):
            scannedacts = []
            if not utils.isSequence(wannabeacts):
                wannabeacts = [wannabeacts]
            for a in wannabeacts:  # scan content of list
                if isinstance(a, vtk.vtkActor):
                    scannedacts.append(a)
                    if hasattr(a, 'trail'
                               ) and a.trail and not a.trail in self.actors:
                        scannedacts.append(a.trail)
                elif isinstance(a, vtk.vtkAssembly):
                    scannedacts.append(a)
                    if a.trail and not a.trail in self.actors:
                        scannedacts.append(a.trail)
                elif isinstance(a, vtk.vtkActor2D):
                    if isinstance(a, vtk.vtkCornerAnnotation):
                        for a2 in settings.collectable_actors:
                            if isinstance(a2, vtk.vtkCornerAnnotation):
                                if at in a2.renderedAt:  # remove old message
                                    self.removeActor(a2)
                        scannedacts.append(a)
                elif isinstance(a, vtk.vtkImageActor):
                    scannedacts.append(a)
                elif isinstance(a, vtk.vtkVolume):
                    scannedacts.append(a)
                elif isinstance(a, vtk.vtkImageData):
                    scannedacts.append(Volume(a))
                elif isinstance(a, vtk.vtkPolyData):
                    scannedacts.append(Actor(a, c, alpha, wire, bc))
                elif isinstance(a, str):  # assume a filepath was given
                    out = vtkio.load(a, c, alpha, wire, bc)
                    if isinstance(out, str):
                        colors.printc("~times File not found:", out, c=1)
                        scannedacts.append(None)
                    else:
                        scannedacts.append(out)
                elif "dolfin" in str(type(a)):  # assume a dolfin.Mesh object
                    from vtkplotter.dolfin import MeshActor
                    out = MeshActor(a, c=c, alpha=alpha, wire=True, bc=bc)
                    scannedacts.append(out)
                elif a is None:
                    pass
                elif isinstance(a, vtk.vtkUnstructuredGrid):
                    gf = vtk.vtkGeometryFilter()
                    gf.SetInputData(a)
                    gf.Update()
                    scannedacts.append(
                        Actor(gf.GetOutput(), c, alpha, wire, bc))
                elif isinstance(a, vtk.vtkStructuredGrid):
                    gf = vtk.vtkGeometryFilter()
                    gf.SetInputData(a)
                    gf.Update()
                    scannedacts.append(
                        Actor(gf.GetOutput(), c, alpha, wire, bc))
                elif isinstance(a, vtk.vtkRectilinearGrid):
                    gf = vtk.vtkRectilinearGridGeometryFilter()
                    gf.SetInputData(a)
                    gf.Update()
                    scannedacts.append(
                        Actor(gf.GetOutput(), c, alpha, wire, bc))
                elif isinstance(a, vtk.vtkMultiBlockDataSet):
                    for i in range(a.GetNumberOfBlocks()):
                        b = a.GetBlock(i)
                        if isinstance(b, vtk.vtkPolyData):
                            scannedacts.append(Actor(b, c, alpha, wire, bc))
                        elif isinstance(b, vtk.vtkImageData):
                            scannedacts.append(Volume(b))
                else:
                    colors.printc("~!? Cannot understand input in show():",
                                  type(a),
                                  c=1)
                    scannedacts.append(None)
            return scannedacts

        if len(actors) == 0:
            actors = None
        elif len(actors) == 1:
            actors = actors[0]
        else:
            actors = utils.flatten(actors)

        if actors is not None:
            self.actors = []
            actors2show = scan(actors)
            for a in actors2show:
                if a not in self.actors:
                    self.actors.append(a)
        else:
            actors2show = scan(self.actors)
            self.actors = list(actors2show)

        if axes is not None:
            self.axes = axes

        if interactive is not None:
            self.interactive = interactive

        if at is None and len(self.renderers) > 1:
            # in case of multiple renderers a call to show w/o specifing
            # at which renderer will just render the whole thing and return
            if self.interactor:
                if zoom:
                    self.camera.Zoom(zoom)
                self.interactor.Render()
                if self.interactive:
                    self.interactor.Start()
                return

        if at is None:
            at = 0

        if at < len(self.renderers):
            self.renderer = self.renderers[at]
        else:
            colors.printc("~times Error in show(): wrong renderer index",
                          at,
                          c=1)
            return

        if not self.camera:
            self.camera = self.renderer.GetActiveCamera()

        self.camera.SetParallelProjection(self.infinity)

        if self.camThickness:
            self.camera.SetThickness(self.camThickness)

        if self.sharecam:
            for r in self.renderers:
                r.SetActiveCamera(self.camera)

        if len(self.renderers) == 1:
            self.renderer.SetActiveCamera(self.camera)

        # rendering
        for ia in actors2show:  # add the actors that are not already in scene
            if ia:
                if isinstance(ia, vtk.vtkVolume):
                    self.renderer.AddVolume(ia)
                else:
                    self.renderer.AddActor(ia)
                if hasattr(ia, 'renderedAt'):
                    ia.renderedAt.add(at)
            else:
                colors.printc(
                    "~lightning Warning: Invalid actor in actors list, skip.",
                    c=5)

        # remove the ones that are not in actors2show
        for ia in self.getActors(at):
            if ia not in actors2show:
                self.renderer.RemoveActor(ia)
                if hasattr(ia, 'renderedAt'):
                    ia.renderedAt.discard(at)

        for c in self.scalarbars:
            self.renderer.RemoveActor(c)
            if hasattr(c, 'renderedAt'):
                c.renderedAt.discard(at)

        if self.axes is not None:
            addons.addAxes()

        addons.addLegend()

        if self.showFrame and len(self.renderers) > 1:
            addons.addFrame()

        if resetcam or self.initializedIren == False:
            self.renderer.ResetCamera()

        if not self.initializedIren and self.interactor:
            self.initializedIren = True
            self.interactor.Initialize()
            self.interactor.RemoveObservers("CharEvent")

            if self.verbose and self.interactive:
                docs.onelinetip()

        self.initializedPlotter = True

        if zoom:
            self.camera.Zoom(zoom)
        if azimuth:
            self.camera.Azimuth(azimuth)
        if elevation:
            self.camera.Elevation(elevation)
        if roll:
            self.camera.Roll(roll)

        if len(viewup):
            if viewup == "x":
                viewup = [1, 0, 0]
            elif viewup == "y":
                viewup = [0, 1, 0]
            elif viewup == "z":
                viewup = [0, 0, 1]
                self.camera.Azimuth(60)
                self.camera.Elevation(30)
            self.camera.Azimuth(0.01)  # otherwise camera gets locked
            self.camera.SetViewUp(viewup)

        self.renderer.ResetCameraClippingRange()

        self.window.Render()

        scbflag = False
        for a in self.actors:
            if (hasattr(a, "scalarbar") and a.scalarbar is not None
                    and utils.isSequence(a.scalarbar)):
                if len(a.scalarbar) == 5:  # addScalarBar
                    s1, s2, s3, s4, s5 = a.scalarbar
                    sb = addons.addScalarBar(a, s1, s2, s3, s4, s5)
                    scbflag = True
                    a.scalarbar = sb  # save scalarbar actor
                elif len(a.scalarbar) == 10:  # addScalarBar3D
                    s0, s1, s2, s3, s4, s5, s6, s7, s8 = a.scalarbar
                    sb = addons.addScalarBar3D(a, at, s0, s1, s2, s3, s4, s5,
                                               s6, s7, s8)
                    scbflag = True
                    a.scalarbar = sb  # save scalarbar actor
        if scbflag:
            self.window.Render()

        if settings.allowInteraction and not self.offscreen:
            self.allowInteraction()

        if settings.interactorStyle is not None:
            interactorStyle = settings.interactorStyle

        if interactorStyle == 0 or interactorStyle == "TrackballCamera":
            pass  # do nothing
        elif interactorStyle == 1 or interactorStyle == "TrackballActor":
            self.interactor.SetInteractorStyle(
                vtk.vtkInteractorStyleTrackballActor())
        elif interactorStyle == 2 or interactorStyle == "JoystickCamera":
            self.interactor.SetInteractorStyle(
                vtk.vtkInteractorStyleJoystickCamera())
        elif interactorStyle == 3 or interactorStyle == "Unicam":
            self.interactor.SetInteractorStyle(vtk.vtkInteractorStyleUnicam())
        elif interactorStyle == 4 or interactorStyle == "Flight":
            self.interactor.SetInteractorStyle(vtk.vtkInteractorStyleFlight())
        elif interactorStyle == 5 or interactorStyle == "RubberBand3D":
            self.interactor.SetInteractorStyle(
                vtk.vtkInteractorStyleRubberBand3D())
        elif interactorStyle == 6 or interactorStyle == "RubberBandZoom":
            self.interactor.SetInteractorStyle(
                vtk.vtkInteractorStyleRubberBandZoom())

        if self.interactor and self.interactive:
            self.interactor.Start()

        if rate:
            if self.clock is None:  # set clock and limit rate
                self._clockt0 = time.time()
                self.clock = 0.0
            else:
                t = time.time() - self._clockt0
                elapsed = t - self.clock
                mint = 1.0 / rate
                if elapsed < mint:
                    time.sleep(mint - elapsed)
                self.clock = time.time() - self._clockt0

        if q:  # gracefully exit
            if self.verbose:
                print("q flag set to True. Exit.")
            sys.exit(0)
예제 #6
0
def slicer(
    volume,
    alpha=1,
    cmaps=('gist_ncar_r', "hot_r", "bone_r", "jet", "Spectral_r"),
    map2cells=False,  # buggy
    clamp=True,
    useSlider3D=False,
    size=(850, 700),
    screensize="auto",
    title="",
    bg="white",
    bg2="lightblue",
    axes=1,
    showHisto=True,
    showIcon=True,
    draggable=False,
    verbose=True,
):
    """
    Generate a ``Plotter`` window with slicing planes for the input Volume.
    Returns the ``Plotter`` object.

    :param float alpha: transparency of the slicing planes
    :param list cmaps: list of color maps names to cycle when clicking button
    :param bool map2cells: scalars are mapped to cells, not intepolated.
    :param bool clamp: clamp scalar to reduce the effect of tails in color mapping
    :param bool useSlider3D: show sliders attached along the axes
    :param list size: rendering window size in pixels
    :param list screensize: size of the screen can be specified
    :param str title: window title
    :param bg: background color
    :param bg2: background gradient color
    :param int axes: axis type number
    :param bool showHisto: show histogram on bottom left
    :param bool showIcon: show a small 3D rendering icon of the volume
    :param bool draggable: make the icon draggable
    """
    global _cmap_slicer

    if verbose: printc("Slicer tool", invert=1, c="m")
    ################################
    vp = Plotter(bg=bg,
                 bg2=bg2,
                 size=size,
                 screensize=screensize,
                 title=title,
                 interactive=False,
                 verbose=verbose)

    ################################
    box = volume.box().wireframe().alpha(0)

    vp.show(box, viewup="z", axes=axes)
    if showIcon:
        vp.showInset(volume,
                     pos=(.85, .85),
                     size=0.15,
                     c='w',
                     draggable=draggable)

    # inits
    la, ld = 0.7, 0.3  #ambient, diffuse
    dims = volume.dimensions()
    data = volume.getPointArray()
    rmin, rmax = volume.imagedata().GetScalarRange()
    sbwidth = 800
    if clamp:
        hdata, edg = np.histogram(data, bins=50)
        logdata = np.log(hdata + 1)
        # mean  of the logscale plot
        meanlog = np.sum(np.multiply(edg[:-1], logdata)) / np.sum(logdata)
        rmax = min(rmax, meanlog + (meanlog - rmin) * 0.9)
        rmin = max(rmin, meanlog - (rmax - meanlog) * 0.9)
        if verbose:
            printc('scalar range clamped to: (' + precision(rmin, 3) + ', ' +
                   precision(rmax, 3) + ')',
                   c='m',
                   bold=0)
    _cmap_slicer = cmaps[0]
    visibles = [None, None, None]
    msh = volume.zSlice(int(dims[2] / 2))
    msh.alpha(alpha).lighting('', la, ld, 0)
    msh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
    if map2cells: msh.mapPointsToCells()
    vp.renderer.AddActor(msh)
    visibles[2] = msh
    addScalarBar(msh,
                 pos=(0.04, 0.0),
                 horizontal=True,
                 width=sbwidth,
                 vmin=rmin,
                 vmax=rmax,
                 titleFontSize=0)

    def sliderfunc_x(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.xSlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[0])
        if i and i < dims[0]: vp.renderer.AddActor(msh)
        visibles[0] = msh

    def sliderfunc_y(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.ySlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[1])
        if i and i < dims[1]: vp.renderer.AddActor(msh)
        visibles[1] = msh

    def sliderfunc_z(widget, event):
        i = int(widget.GetRepresentation().GetValue())
        msh = volume.zSlice(i).alpha(alpha).lighting('', la, ld, 0)
        msh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
        if map2cells: msh.mapPointsToCells()
        vp.renderer.RemoveActor(visibles[2])
        if i and i < dims[2]: vp.renderer.AddActor(msh)
        visibles[2] = msh

    cx, cy, cz, ch = 'dr', 'dg', 'db', (0.3, 0.3, 0.3)
    if np.sum(vp.renderer.GetBackground()) < 1.5:
        cx, cy, cz = 'lr', 'lg', 'lb'
        ch = (0.8, 0.8, 0.8)

    if not useSlider3D:
        vp.addSlider2D(sliderfunc_x,
                       0,
                       dims[0],
                       title='X',
                       pos=[(0.8, 0.12), (0.95, 0.12)],
                       showValue=False,
                       c=cx)
        vp.addSlider2D(sliderfunc_y,
                       0,
                       dims[1],
                       title='Y',
                       pos=[(0.8, 0.08), (0.95, 0.08)],
                       showValue=False,
                       c=cy)
        vp.addSlider2D(sliderfunc_z,
                       0,
                       dims[2],
                       title='Z',
                       value=int(dims[2] / 2),
                       pos=[(0.8, 0.04), (0.95, 0.04)],
                       showValue=False,
                       c=cz)
    else:  # 3d sliders attached to the axes bounds
        bs = box.bounds()
        vp.addSlider3D(
            sliderfunc_x,
            pos1=(bs[0], bs[2], bs[4]),
            pos2=(bs[1], bs[2], bs[4]),
            xmin=0,
            xmax=dims[0],
            t=box.diagonalSize() / mag(box.xbounds()) * 0.6,
            c=cx,
            showValue=False,
        )
        vp.addSlider3D(
            sliderfunc_y,
            pos1=(bs[1], bs[2], bs[4]),
            pos2=(bs[1], bs[3], bs[4]),
            xmin=0,
            xmax=dims[1],
            t=box.diagonalSize() / mag(box.ybounds()) * 0.6,
            c=cy,
            showValue=False,
        )
        vp.addSlider3D(
            sliderfunc_z,
            pos1=(bs[0], bs[2], bs[4]),
            pos2=(bs[0], bs[2], bs[5]),
            xmin=0,
            xmax=dims[2],
            value=int(dims[2] / 2),
            t=box.diagonalSize() / mag(box.zbounds()) * 0.6,
            c=cz,
            showValue=False,
        )

    #################
    def buttonfunc():
        global _cmap_slicer
        bu.switch()
        _cmap_slicer = bu.status()
        for mesh in visibles:
            if mesh:
                mesh.pointColors(cmap=_cmap_slicer, vmin=rmin, vmax=rmax)
                if map2cells:
                    mesh.mapPointsToCells()
        vp.renderer.RemoveActor(mesh.scalarbar)
        mesh.scalarbar = addScalarBar(mesh,
                                      pos=(0.04, 0.0),
                                      horizontal=True,
                                      width=sbwidth,
                                      vmin=rmin,
                                      vmax=rmax,
                                      titleFontSize=0)
        vp.renderer.AddActor(mesh.scalarbar)

    bu = vp.addButton(
        buttonfunc,
        pos=(0.27, 0.005),
        states=cmaps,
        c=["db"] * len(cmaps),
        bc=["lb"] * len(cmaps),  # colors of states
        size=14,
        bold=True,
    )

    #################
    hist = None
    if showHisto:
        hist = cornerHistogram(data,
                               s=0.2,
                               bins=25,
                               logscale=1,
                               pos=(0.02, 0.02),
                               c=ch,
                               bg=ch,
                               alpha=0.7)


#    vp.backgroundRenderer = vtk.vtkRenderer()
#    vp.backgroundRenderer.SetLayer(1)
#    vp.backgroundRenderer.InteractiveOff()
#    actor = histogram(data, logscale=1, alpha=0.8).scale(4/150)
#    vp.window.AddRenderer(vp.backgroundRenderer)
#    vp.backgroundRenderer.AddActor(actor)
#    cam = vtk.vtkCamera()
#    cam.SetPosition( -10,-10, 40)
#    #actor.SetPosition(-4,-4,  0)
#    actor.SetOrigin(-8,-8,0)
#    cam.SetParallelScale(1)
#    vp.backgroundRenderer.SetActiveCamera(cam)
#    vp.backgroundRenderer.ResetCameraClippingRange()

    comment = None
    if verbose:
        comment = Text2D(
            "Use sliders to slice volume\nClick button to change colormap",
            font='Montserrat',
            s=0.8)

    vp.show(msh, hist, comment, interactive=False)
    vp.interactive = True
    if verbose:
        printc("Press button to cycle through color maps:\n", cmaps, c="m")
        printc("Use sliders to select the slicing planes.", c="m")
    return vp