예제 #1
0
class MainWindow(Qt.QMainWindow):
    def __init__(self, parent=None):

        Qt.QMainWindow.__init__(self, parent)
        self.frame = Qt.QFrame()
        self.layout = Qt.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)

        # Create vedo renderer and add objects and callbacks
        self.vp = Plotter(qtWidget=self.vtkWidget)
        self.cbid = self.vp.addCallback("key press", self.onKeypress)
        self.imgActor = Picture(
            "https://icatcare.org/app/uploads/2018/07/Helping-your-new-cat-or-kitten-settle-in-1.png"
        )
        self.text2d = Text2D("Use slider to change contrast")

        self.slider = Qt.QSlider(1)
        self.slider.valueChanged.connect(self.onSlider)
        self.layout.addWidget(self.vtkWidget)
        self.layout.addWidget(self.slider)

        self.frame.setLayout(self.layout)
        self.setCentralWidget(self.frame)
        self.vp.show(self.imgActor, self.text2d,
                     mode='image')  # build the vedo rendering
        self.show()  # show the Qt Window

    def onSlider(self, value):
        self.imgActor.window(value * 10)  # change image contrast
        self.text2d.text(f"window level is now: {value*10}")
        self.vp.render()

    def onKeypress(self, evt):
        printc("You have pressed key:", evt.keyPressed, c='b')
        if evt.keyPressed == 'q':
            self.vp.close()
            self.vtkWidget.close()
            exit()

    def onClose(self):
        self.vtkWidget.close()
예제 #2
0
        y_dot[k] -= Dt * Ks * (bob_y_m[k] - bob_y_m[k + 1]) * factor

    # Check to see if they are colliding
    for i in range(1, N):
        for j in range(i + 1, N + 1):
            dist2 = (bob_x[i] - bob_x[j])**2 + (bob_y[i] - bob_y[j])**2
            if dist2 < DiaSq:  # are colliding
                Ddist = np.sqrt(dist2) - 2 * R
                tau = versor([bob_x[j] - bob_x[i], bob_y[j] - bob_y[i], 0])
                DR = Ddist / 2 * tau
                bob_x[i] += DR[0]  # DR.x
                bob_y[i] += DR[1]  # DR.y
                bob_x[j] -= DR[0]  # DR.x
                bob_y[j] -= DR[1]  # DR.y
                Vji = vector(x_dot[j] - x_dot[i], y_dot[j] - y_dot[i])
                DV = np.dot(Vji, tau) * tau
                x_dot[i] += DV[0]  # DV.x
                y_dot[i] += DV[1]  # DV.y
                x_dot[j] -= DV[0]  # DV.x
                y_dot[j] -= DV[1]  # DV.y

    # Update the loations of the bobs and the stretching of the springs
    for k in range(1, N + 1):
        bob[k].pos([bob_x[k], bob_y[k], 0])
        link[k - 1].stretch(bob[k - 1].pos(), bob[k].pos())

    plt.show()
    if plt.escaped: break  # if ESC is hit during the loop

plt.close()
예제 #3
0
                    resetcam=True,
                    sharecam=False,
                    offscreen=True)
    vplt1.show(coloredMesh,
               verPoints,
               title='Patient{}, Back View'.format(patient),
               camera=cam1)
    video1.addFrame()

    vplt2 = Plotter(offscreen=True)
    errplt = plot(x,
                  y,
                  'o',
                  title='Patient{}, \DeltaE(m)'.format(patient),
                  xtitle='m',
                  ytitle=r'\DeltaE',
                  xlim=[0, m + 1],
                  ylim=[0, ymax],
                  axes={'xyPlaneColor': 'white'})
    vplt2.show(errplt)
    video2.addFrame()

    if m != stop - 1:
        vplt0.close()
        vplt1.close()
        vplt2.close()

video0.close()
video1.close()
video2.close()
TstIdx = sorted(np.take(latIdx, tst_i))

# get vertex coordinates
TrCoord = [vertices[i] for i in TrIdx]
TstCoord = [vertices[i] for i in TstIdx]

# get mapLAT signal values
TrVal = [mapLAT[i] for i in TrIdx]
TstVal = [mapLAT[i] for i in TstIdx]


""" MAGIC-LAT estimate """
latEst = magicLAT(vertices, faces, TrIdx, TrCoord, TrVal, EDGE_THRESHOLD)

magicDE = metrics.deltaE(TstVal, latEst[TstIdx], MINLAT, MAXLAT)

verPoints = Points(TrCoord, r=5).cmap('gist_rainbow', TrVal, vmin=MINLAT, vmax=MAXLAT).addScalarBar()
estPoints = Points(vertices, r=5).cmap('gist_rainbow', latEst, vmin=MINLAT, vmax=MAXLAT).addScalarBar()
coloredMesh = Mesh([vertices, faces])
coloredMesh.interpolateDataFrom(estPoints, N=1).cmap('gist_rainbow', vmin=MINLAT, vmax=MAXLAT).addScalarBar()


vplt0 = Plotter(N=1, bg='black', resetcam=True, sharecam=False, offscreen=True)
vplt0.show(coloredMesh, verPoints, title='Patient{}, Front View'.format(patient), camera=cam0)

# video0.action(cam1=cam0, cam2=cam1)
video0.action(azimuth_range=(0, 359))
video0.close()
vplt0.close()

예제 #5
0
class Render:
    is_rendered = False
    plotter = None

    axes_names = ("AP", "DV", "LR")
    axes_lookup = {"x": "AP", "y": "DV", "z": "LR"}
    axes_indices = {"AP": 0, "DV": 1, "LR": 2}

    def __init__(self, plotter=None):
        """
        Backend for Scene, handles all rendering and exporting
        related tasks.
        """
        if plotter is None:
            self._get_plotter()
        else:
            self.plotter = plotter
            self.plotter.keyPressFunction = self.keypress

    def _get_plotter(self):
        """
        Make a vedo plotter with
        fancy axes and all
        """
        self.plotter = Plotter(
            axes=self._make_axes() if settings.SHOW_AXES else None,
            pos=(0, 0),
            title="brainrender",
            bg=settings.BACKGROUND_COLOR,
            offscreen=settings.OFFSCREEN,
            size="full" if settings.WHOLE_SCREEN else "auto",
        )

        self.plotter.keyPressFunction = self.keypress

    def _make_axes(self):
        """
        Returns a dictionary with axes
        parameters for the vedo plotter
        """
        ax_idx = self.atlas.space.axes_order.index("frontal")

        # make acustom axes dict
        atlas_shape = np.array(self.atlas.metadata["shape"]) * np.array(
            self.atlas.metadata["resolution"]
        )
        z_range = np.array([-atlas_shape[2], 0])
        z_ticks = [
            (-v, str(np.abs(v).astype(np.int32)))
            for v in np.linspace(
                0,
                atlas_shape[ax_idx],
                10,
            )
        ]

        if self.atlas.atlas_name == "allen_human_500um":
            z_range = None
            z_ticks = None
            logger.debug(
                "RENDER: manually forcing axes size for human atlas, atlas needs fixing"
            )

        # make custom axes dict
        axes = dict(
            axesLineWidth=3,
            tipSize=0,
            xtitle="AP (μm)",
            ytitle="DV (μm)",
            ztitle="LR (μm)",
            textScale=0.8,
            xTitleRotation=180,
            zrange=z_range,
            zValuesAndLabels=z_ticks,
            xyGrid=False,
            yzGrid=False,
            zxGrid=False,
            xUseBounds=True,
            yUseBounds=True,
            zUseBounds=True,
            xLabelRotation=180,
            yLabelRotation=180,
            zLabelRotation=90,
        )

        return axes

    def _prepare_actor(self, actor):
        """
        When an actor is first rendered, a transform matrix
        is applied to its points to correct axes orientation
        mismatches: https://github.com/brainglobe/bg-atlasapi/issues/73

        Once an actor is 'corrected' it spawns labels and silhouettes as needed
        """
        # don't apply transforms to points density actors
        if isinstance(actor, PointsDensity):
            logger.debug(
                f'Not transforming actor "{actor.name} (type: {actor.br_class})"'
            )
            actor._is_transformed = True

        # Flip every actor's orientation
        if not actor._is_transformed:
            try:
                actor._mesh = actor.mesh.clone()
                actor._mesh.applyTransform(mtx)
            except AttributeError:  # some types of actors dont trasform
                logger.debug(
                    f'Failed to transform actor: "{actor.name} (type: {actor.br_class})"'
                )
                actor._is_transformed = True
            else:
                try:
                    actor.mesh.reverse()
                except AttributeError:  # Volumes don't have reverse
                    logger.debug(
                        f'Failed to reverse actor: "{actor.name} (type: {actor.br_class})"'
                    )
                    pass
                actor._is_transformed = True

        # Add silhouette and labels
        if actor._needs_silhouette and not self.backend:
            self.plotter.add(actor.make_silhouette().mesh)

        if actor._needs_label and not self.backend:
            self.labels.extend(actor.make_label(self.atlas))

    def _apply_style(self):
        """
        Sets the rendering style for each mesh
        """
        for actor in self.clean_actors:
            if settings.SHADER_STYLE != "cartoon":
                style = settings.SHADER_STYLE
            else:
                if self.backend:  # notebook backend
                    print(
                        'Shader style "cartoon" cannot be used in a notebook'
                    )
                style = "off"

            try:
                actor.mesh.reverse()  # flip normals
                actor.mesh.lighting(style=style)

                actor._mesh.reverse()
                actor._mesh.lighting(style=style)
            except AttributeError:
                pass

    def render(
        self,
        interactive=None,
        camera=None,
        zoom=None,
        update_camera=True,
        **kwargs,
    ):
        """
        Renders the scene.

        :param interactive: bool. If note settings.INTERACTIVE is used.
            If true the program's execution is stopped and users
            can interact with scene.
        :param camera: str, dict. If none the default camera is used.
            Pass a valid camera input to specify the camera position when
            the scene is rendered.
        :param zoom: float, if None atlas default is used
        :param update_camera: bool, if False the camera is not changed
        :param kwargs: additional arguments to pass to self.plotter.show
        """
        logger.debug(
            f"Rendering scene. Interactive: {interactive}, camera: {camera}, zoom: {zoom}"
        )
        # get zoom
        zoom = zoom or self.atlas.zoom

        # get vedo plotter
        if self.plotter is None:
            self._get_plotter()

        # Get camera
        camera = camera or settings.DEFAULT_CAMERA
        if isinstance(camera, str):
            camera = get_camera(camera)
        else:
            camera = check_camera_param(camera)

        if "focalPoint" not in camera.keys() or camera["focalPoint"] is None:
            camera["focalPoint"] = self.root._mesh.centerOfMass()

        if not self.backend and camera is not None:
            camera = set_camera(self, camera)

        # Apply axes correction
        for actor in self.clean_actors:
            if not actor._is_transformed:
                self._prepare_actor(actor)
                self.plotter.add(actor.mesh)

            if actor._needs_silhouette or actor._needs_label:
                self._prepare_actor(actor)

        # add labels to the scene
        for label in self.labels:
            if label._is_added:
                continue
            else:
                label._mesh = label.mesh.clone()
                self._prepare_actor(label)
                self.plotter.add(label._mesh.reverse())
                label._is_added = True

        # Apply style
        self._apply_style()

        if self.inset and not self.is_rendered:
            self._get_inset()

        # render
        self.is_rendered = True
        if not self.backend:  # not running in a python script
            if interactive is None:
                interactive = settings.INTERACTIVE

            self.plotter.show(
                interactive=interactive,
                zoom=zoom,
                bg=settings.BACKGROUND_COLOR,
                camera=camera.copy() if update_camera else None,
                interactorStyle=0,
                rate=40,
            )
        elif self.backend == "k3d":  # pragma: no cover
            # Remove silhouettes
            self.remove(*self.get_actors(br_class="silhouette"))
            print(
                f"[{teal}]Your scene is ready for rendering, use:\n",
                Syntax("from vedo import show", lexer_name="python"),
                Syntax("vedo.show(*scene.renderables)", lexer_name="python"),
                sep="\n",
            )
        else:  # pragma: no cover
            print(
                f"[{teal}]Your scene is ready for rendering, use:\n",
                Syntax("from itkwidgets import view", lexer_name="python"),
                Syntax(
                    "view(scene.plotter.show(*scene.renderables))",
                    lexer_name="python",
                ),
                sep="\n",
            )

    def close(self):
        self.plotter.close()

    def export(self, savepath):
        """
        Exports the scene to a .html
        file for online renderings.

        :param savepath: str, Path to a .html file to save the export
        """
        logger.debug(f"Exporting scene to {savepath}")
        _backend = self.backend

        if not self.is_rendered:
            self.render(interactive=False)

        path = Path(savepath)
        if path.suffix != ".html":
            raise ValueError("Savepath should point to a .html file")

        # prepare settings
        vsettings.notebookBackend = "k3d"

        # Create new plotter and save to file
        plt = Plotter()
        plt.add(self.clean_renderables, render=False)
        plt = plt.show(interactive=False)
        plt.camera[-2] = -1

        with open(path, "w") as fp:
            fp.write(plt.get_snapshot())

        print(
            f"The brainrender scene has been exported for web. The results are saved at {path}"
        )

        # Reset settings
        vsettings.notebookBackend = None
        self.backend = _backend

        return str(path)

    def screenshot(self, name=None, scale=None):
        """
        Takes a screenshot of the current view
        and save it to file.
        Screenshots are saved in `screenshots_folder`
        (see Scene)

        :param name: str, name of png file
        :param scale: float, >1 for higher resolution
        """

        if not self.is_rendered:
            self.render(interactive=False)

        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        name = name or f"brainrender_screenshot_{timestamp}"
        if ".png" not in name:
            name += ".png"

        scale = scale or settings.SCREENSHOT_SCALE

        print(f"\nSaving new screenshot at {name}\n")

        savepath = str(self.screenshots_folder / name)
        logger.debug(f"Saving scene at {savepath}")
        self.plotter.screenshot(filename=savepath, scale=scale)
        return savepath

    def _print_camera(self):
        pms = get_camera_params(scene=self)

        focal = pms.pop("focalPoint", None)
        dst = pms.pop("distance", None)

        names = [
            f"[green bold]     '{k}'[/green bold]: [{amber}]{v},"
            for k, v in pms.items()
        ]
        print(
            f"[{deep_purple_light}]Camera parameters:",
            f"[{orange}]    {{",
            *names,
            f"[{orange}]   }}",
            f"[{deep_purple_light}]Additional, (optional) parameters:",
            f"[green bold]     'focalPoint'[/green bold]: [{amber}]{focal},",
            f"[green bold]     'distance'[/green bold]: [{amber}]{dst},",
            sep="\n",
        )

    def keypress(self, key):  # pragma: no cover
        """
        Hanles key presses for interactive view
        -s: take's a screenshot
        -q: closes the window
        -c: prints the current camera parameters
        """
        if key == "s":
            self.screenshot()

        elif key == "q" or key == "Esc":
            self.close()

        elif key == "c":
            self._print_camera()
예제 #6
0
                                                   OrigLatCoords, OrigLatVals)

M = len(allLatIdx)

# For colorbar ranges
MINLAT = math.floor(min(allLatVal) / 10) * 10
MAXLAT = math.ceil(max(allLatVal) / 10) * 10

allPoints = Points(allLatCoord, r=10).cmap('gist_rainbow',
                                           allLatVal,
                                           vmin=MINLAT,
                                           vmax=MAXLAT).addScalarBar(c='white')

vplt = Plotter(N=1, axes=0, interactive=True)
for i in range(M):
    idx = allLatIdx[i]
    coord = allLatCoord[i]
    val = allLatVal[i]

    # plot current point as larger than the others
    testPoint = Point(coord, r=20).cmap('gist_rainbow', [val],
                                        vmin=MINLAT,
                                        vmax=MAXLAT).addScalarBar(c='white')
    vplt.show(mesh,
              allPoints,
              testPoint,
              title='i={:g}/{:g}'.format(i, M),
              bg='black')

vplt.close()