Esempio n. 1
0
def getNotebookBackend(actors2show, zoom, viewup):

    vp = settings.plotter_instance

    ####################################################################################
    # https://github.com/InsightSoftwareConsortium/itkwidgets
    #  /blob/master/itkwidgets/widget_viewer.py
    if 'itk' in settings.notebookBackend:
        from itkwidgets import view

        if sum(vp.shape) != 2:
            colors.printc(
                "Warning: multirendering is not supported in jupyter.", c=1)

#        settings.notebook_plotter = view(actors=actors2show,
#                                         cmap='jet', ui_collapsed=True,
#                                         gradient_opacity=False)

        polys2show = []
        points2show = []
        imgs2show = []
        polycols, polyalphas, pointcols, pointalphas = [], [], [], []

        for ia in actors2show:

            if isinstance(ia, Assembly):  #unpack assemblies
                acass = ia.getActors()
                for ac in acass:
                    if ac.polydata().GetNumberOfPolys():
                        polys2show.append(ac.polydata())
                        polycols.append(ac.color())
                        polyalphas.append(ac.alpha())
                    else:
                        points2show.append(ac.polydata())
                        pointcols.append(ac.color())
                        pointalphas.append(ac.alpha())

            elif isinstance(ia, Actor):
                if ia.polydata().GetNumberOfPolys():
                    polys2show.append(ia.polydata())
                    polycols.append(ia.color())
                    polyalphas.append(ia.alpha())
                else:
                    points2show.append(ia.polydata())
                    pointcols.append(ia.color())
                    pointalphas.append(ia.alpha())

            elif isinstance(ia, Volume):
                imgs2show.append(ia.imagedata())

        img = None
        if len(imgs2show):
            img = imgs2show[0]

        settings.notebook_plotter = view(
            image=img,
            geometries=polys2show,
            geometry_colors=polycols,
            geometry_opacities=polyalphas,
            point_sets=points2show,
            point_set_colors=pointcols,
            point_set_opacities=pointalphas,
            cmap='jet',
            ui_collapsed=True,
            gradient_opacity=False,
        )

    ####################################################################################
    elif settings.notebookBackend == 'k3d':
        import k3d  # https://github.com/K3D-tools/K3D-jupyter

        if vp.shape[0] != 1 or vp.shape[1] != 1:
            colors.printc(
                "Warning: multirendering is not supported in jupyter.", c=1)

        actors2show2 = []
        for ia in actors2show:
            if isinstance(ia, vtk.vtkAssembly):  #unpack assemblies
                acass = ia.getActors()
                actors2show2 += acass
            else:
                actors2show2.append(ia)

        vbb, sizes, min_bns, max_bns = addons.computeVisibleBounds()
        kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5]

        settings.notebook_plotter = k3d.plot(
            axes=[vp.xtitle, vp.ytitle, vp.ztitle],
            menu_visibility=True,
            height=int(vp.size[1] / 2))
        settings.notebook_plotter.grid = kgrid
        settings.notebook_plotter.lighting = 1.2

        # set k3d camera
        settings.notebook_plotter.camera_auto_fit = False

        eps = 1 + numpy.random.random() * 1.0e-04  # workaround to bug in k3d
        # https://github.com/K3D-tools/K3D-jupyter/issues/180

        if settings.plotter_instance and settings.plotter_instance.camera:
            k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera)
            k3dc[2] = k3dc[2] * eps
            settings.notebook_plotter.camera = k3dc
            #print('k3dcr', k3dc*eps)
        else:
            vsx, vsy, vsz = vbb[0] - vbb[1], vbb[2] - vbb[3], vbb[4] - vbb[5]
            vss = numpy.linalg.norm([vsx, vsy, vsz])
            if zoom:
                vss /= zoom
            vfp = (vbb[0] + vbb[1]) / 2, (vbb[2] + vbb[3]) / 2, (
                vbb[4] + vbb[5]) / 2  # camera target
            if viewup == 'z':
                vup = (0, 0, 1)  # camera up vector
                vpos = vfp[0] + vss / 1.9, vfp[1] + vss / 1.9, vfp[
                    2] + vss * 0.01  # camera position
            elif viewup == 'x':
                vup = (1, 0, 0)
                vpos = vfp[0] + vss * 0.01, vfp[1] + vss / 1.5, vfp[
                    2]  # camera position
            else:
                vup = (0, 1, 0)
                vpos = vfp[0] + vss * 0.01, vfp[1] + vss * 0.01, vfp[
                    2] + vss / 1.5  # camera position
            settings.notebook_plotter.camera = [
                vpos[0], vpos[1], vpos[2] * eps, vfp[0], vfp[1], vfp[2],
                vup[0], vup[1], vup[2]
            ]
        if not vp.axes:
            settings.notebook_plotter.grid_visible = False

        for ia in actors2show2:
            kobj = None
            kcmap = None

            if isinstance(ia, Actor) and ia.N():

                iap = ia.GetProperty()
                #ia.clean().triangle().computeNormals()
                #ia.triangle()
                iapoly = ia.clone().clean().triangle().computeNormals(
                ).polydata()

                vtkscals = None
                color_attribute = None
                if ia.mapper.GetScalarVisibility():
                    vtkdata = iapoly.GetPointData()
                    vtkscals = vtkdata.GetScalars()

                    if vtkscals is None:
                        vtkdata = iapoly.GetCellData()
                        vtkscals = vtkdata.GetScalars()
                        if vtkscals is not None:
                            c2p = vtk.vtkCellDataToPointData()
                            c2p.SetInputData(iapoly)
                            c2p.Update()
                            iapoly = c2p.GetOutput()
                            vtkdata = iapoly.GetPointData()
                            vtkscals = vtkdata.GetScalars()

                    if vtkscals is not None:
                        if not vtkscals.GetName():
                            vtkscals.SetName('scalars')
                        scals_min, scals_max = ia.mapper.GetScalarRange()
                        color_attribute = (vtkscals.GetName(), scals_min,
                                           scals_max)
                        lut = ia.mapper.GetLookupTable()
                        lut.Build()
                        kcmap = []
                        nlut = lut.GetNumberOfTableValues()
                        for i in range(nlut):
                            r, g, b, a = lut.GetTableValue(i)
                            kcmap += [i / (nlut - 1), r, g, b]

                if iapoly.GetNumberOfPolys() > 0:
                    name = None
                    if ia.filename:
                        name = os.path.basename(ia.filename)
                    kobj = k3d.vtk_poly_data(
                        iapoly,
                        name=name,
                        color=colors.rgb2int(iap.GetColor()),
                        color_attribute=color_attribute,
                        color_map=kcmap,
                        opacity=iap.GetOpacity(),
                        wireframe=(iap.GetRepresentation() == 1))

                    if iap.GetInterpolation() == 0:
                        kobj.flat_shading = True

                else:
                    kcols = []
                    if color_attribute is not None:
                        scals = vtk_to_numpy(vtkscals)
                        kcols = k3d.helpers.map_colors(
                            scals, kcmap,
                            [scals_min, scals_max]).astype(numpy.uint32)
                    sqsize = numpy.sqrt(numpy.dot(sizes, sizes))

                    if ia.NPoints() == ia.NCells():
                        kobj = k3d.points(
                            ia.coordinates().astype(numpy.float32),
                            color=colors.rgb2int(iap.GetColor()),
                            colors=kcols,
                            opacity=iap.GetOpacity(),
                            shader="3d",
                            point_size=iap.GetPointSize() * sqsize / 400,
                            #compression_level=9,
                        )
                    else:
                        kobj = k3d.line(
                            ia.coordinates().astype(numpy.float32),
                            color=colors.rgb2int(iap.GetColor()),
                            colors=kcols,
                            opacity=iap.GetOpacity(),
                            shader="thick",
                            width=iap.GetLineWidth() * sqsize / 1000,
                        )

                settings.notebook_plotter += kobj

            elif isinstance(ia, Volume):
                kx, ky, kz = ia.dimensions()
                arr = ia.getPointArray()
                kimage = arr.reshape(-1, ky, kx)

                colorTransferFunction = ia.GetProperty(
                ).GetRGBTransferFunction()
                kcmap = []
                for i in range(128):
                    r, g, b = colorTransferFunction.GetColor(i / 127)
                    kcmap += [i / 127, r, g, b]

                #print('vol scal range', ia.imagedata().GetScalarRange())
                #print(numpy.min(kimage), numpy.max(kimage))

                kbounds = numpy.array(ia.imagedata().GetBounds()) \
                    + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\
                    * numpy.array([-1,1] * 3)

                kobj = k3d.volume(
                    kimage.astype(numpy.float32),
                    color_map=kcmap,
                    #color_range=ia.imagedata().GetScalarRange(),
                    alpha_coef=10,
                    bounds=kbounds,
                )
                settings.notebook_plotter += kobj

            elif hasattr(ia, 'info') and 'formula' in ia.info.keys():
                pos = (ia.GetPosition()[0], ia.GetPosition()[1])
                kobj = k3d.text2d(ia.info['formula'], position=pos)
                settings.notebook_plotter += kobj

    ####################################################################################
    elif settings.notebookBackend == 'panel' and hasattr(
            vp, 'window') and vp.window:
        import panel  # https://panel.pyviz.org/reference/panes/VTK.html
        settings.notebook_plotter = panel.pane.VTK(vp.window,
                                                   width=int(vp.size[0] / 2),
                                                   height=int(vp.size[1] / 2))

    return settings.notebook_plotter
Esempio n. 2
0
def getNotebookBackend(actors2show, zoom, viewup):

    vp = settings.plotter_instance

    if isinstance(vp.shape, str) or sum(vp.shape) > 2:
        colors.printc("Multirendering is not supported in jupyter.", c=1)
        return

    ####################################################################################
    # https://github.com/InsightSoftwareConsortium/itkwidgets
    #  /blob/master/itkwidgets/widget_viewer.py
    if 'itk' in settings.notebookBackend:
        from itkwidgets import view

        settings.notebook_plotter = view(actors=actors2show,
                                         cmap='jet',
                                         ui_collapsed=True,
                                         gradient_opacity=False)

    ####################################################################################
    elif settings.notebookBackend == 'k3d':
        try:
            import k3d  # https://github.com/K3D-tools/K3D-jupyter
        except:
            print("Cannot find k3d, install with:  pip install k3d")
            return

        actors2show2 = []
        for ia in actors2show:
            if not ia:
                continue
            if isinstance(ia, vtk.vtkAssembly):  #unpack assemblies
                acass = ia.unpack()
                actors2show2 += acass
            else:
                actors2show2.append(ia)

        # vbb, sizes, _, _ = addons.computeVisibleBounds()
        # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5]

        settings.notebook_plotter = k3d.plot(
            axes=[vp.xtitle, vp.ytitle, vp.ztitle],
            menu_visibility=True,
            # height=int(vp.size[1]/2),
        )
        # settings.notebook_plotter.grid = kgrid
        settings.notebook_plotter.lighting = 1.2

        # set k3d camera
        settings.notebook_plotter.camera_auto_fit = True

        if settings.plotter_instance and settings.plotter_instance.camera:
            k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera)
            if zoom:
                k3dc[0] /= zoom
                k3dc[1] /= zoom
                k3dc[2] /= zoom
            settings.notebook_plotter.camera = k3dc
        # else:
        #     vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5]
        #     vss = numpy.linalg.norm([vsx, vsy, vsz])
        #     if zoom:
        #         vss /= zoom
        #     vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target
        #     if viewup == 'z':
        #         vup = (0,0,1) # camera up vector
        #         vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01  # camera position
        #     elif viewup == 'x':
        #         vup = (1,0,0)
        #         vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2]  # camera position
        #     else:
        #         vup = (0,1,0)
        #         vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5  # camera position
        #     settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2],
        #                                           vfp[0],  vfp[1],  vfp[2],
        #                                           vup[0],  vup[1],  vup[2] ]
        if not vp.axes:
            settings.notebook_plotter.grid_visible = False

        for ia in actors2show2:

            if isinstance(ia, (vtk.vtkCornerAnnotation, vtk.vtkAssembly)):
                continue

            kobj = None
            kcmap = None
            name = None
            if hasattr(ia, 'filename'):
                if ia.filename:
                    name = os.path.basename(ia.filename)
                if ia.name:
                    name = os.path.basename(ia.name)

            #####################################################################scalars
            # work out scalars first, Points Lines are also Mesh objs
            if isinstance(ia, (Mesh, shapes.Line, Points)):
                #                print('scalars', ia.name, ia.N())
                iap = ia.GetProperty()

                if isinstance(ia, (shapes.Line, Points)):
                    iapoly = ia.polydata()
                else:
                    iapoly = ia.clone().clean().triangulate().computeNormals(
                    ).polydata()

                vtkscals = None
                color_attribute = None
                if ia.mapper().GetScalarVisibility():
                    vtkdata = iapoly.GetPointData()
                    vtkscals = vtkdata.GetScalars()

                    if vtkscals is None:
                        vtkdata = iapoly.GetCellData()
                        vtkscals = vtkdata.GetScalars()
                        if vtkscals is not None:
                            c2p = vtk.vtkCellDataToPointData()
                            c2p.SetInputData(iapoly)
                            c2p.Update()
                            iapoly = c2p.GetOutput()
                            vtkdata = iapoly.GetPointData()
                            vtkscals = vtkdata.GetScalars()

                    if vtkscals is not None:
                        if not vtkscals.GetName():
                            vtkscals.SetName('scalars')
                        scals_min, scals_max = ia.mapper().GetScalarRange()
                        color_attribute = (vtkscals.GetName(), scals_min,
                                           scals_max)
                        lut = ia.mapper().GetLookupTable()
                        lut.Build()
                        kcmap = []
                        nlut = lut.GetNumberOfTableValues()
                        for i in range(nlut):
                            r, g, b, a = lut.GetTableValue(i)
                            kcmap += [i / (nlut - 1), r, g, b]

            #####################################################################Volume
            if isinstance(ia, Volume):
                #                print('Volume', ia.name, ia.dimensions())
                kx, ky, kz = ia.dimensions()
                arr = ia.getPointArray()
                kimage = arr.reshape(-1, ky, kx)

                colorTransferFunction = ia.GetProperty(
                ).GetRGBTransferFunction()
                kcmap = []
                for i in range(128):
                    r, g, b = colorTransferFunction.GetColor(i / 127)
                    kcmap += [i / 127, r, g, b]

                kbounds = numpy.array(ia.imagedata().GetBounds()) \
                    + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\
                    * numpy.array([-1,1] * 3)

                kobj = k3d.volume(
                    kimage.astype(numpy.float32),
                    color_map=kcmap,
                    #color_range=ia.imagedata().GetScalarRange(),
                    alpha_coef=10,
                    bounds=kbounds,
                    name=name,
                )
                settings.notebook_plotter += kobj

            #####################################################################text
            elif hasattr(ia, 'info') and 'formula' in ia.info.keys():
                pos = (ia.GetPosition()[0], ia.GetPosition()[1])
                kobj = k3d.text2d(ia.info['formula'], position=pos)
                settings.notebook_plotter += kobj

            #####################################################################Mesh
            elif isinstance(ia, Mesh) and ia.N() and len(ia.faces()):
                # print('Mesh', ia.name, ia.N(), len(ia.faces()))
                kobj = k3d.vtk_poly_data(
                    iapoly,
                    name=name,
                    # color=_rgb2int(iap.GetColor()),
                    color_attribute=color_attribute,
                    color_map=kcmap,
                    opacity=iap.GetOpacity(),
                    wireframe=(iap.GetRepresentation() == 1))

                if iap.GetInterpolation() == 0:
                    kobj.flat_shading = True
                settings.notebook_plotter += kobj

            #####################################################################Points
            elif isinstance(ia, Points) or ia.NPoints() == ia.NCells():
                # print('Points', ia.name, ia.N())
                kcols = []
                if color_attribute is not None:
                    scals = vtk_to_numpy(vtkscals)
                    kcols = k3d.helpers.map_colors(
                        scals, kcmap,
                        [scals_min, scals_max]).astype(numpy.uint32)
                # sqsize = numpy.sqrt(numpy.dot(sizes, sizes))

                kobj = k3d.points(
                    ia.points().astype(numpy.float32),
                    color=_rgb2int(iap.GetColor()),
                    colors=kcols,
                    opacity=iap.GetOpacity(),
                    shader="dot",
                    point_size=3,  # point_size=iap.GetPointSize()*sqsize/800,
                    name=name,
                )
                settings.notebook_plotter += kobj

            #####################################################################Line
            elif ia.polydata(False).GetNumberOfLines():
                # print('Line', ia.name, ia.N(), len(ia.faces()),
                #       ia.polydata(False).GetNumberOfLines(), len(ia.lines()),
                #       color_attribute, [vtkscals])

                # kcols=[]
                # if color_attribute is not None:
                #     scals = vtk_to_numpy(vtkscals)
                #     kcols = k3d.helpers.map_colors(scals, kcmap,
                #                                    [scals_min,scals_max]).astype(numpy.uint32)

                # sqsize = numpy.sqrt(numpy.dot(sizes, sizes))

                for i, ln_idx in enumerate(ia.lines()):
                    if i > 200:
                        print(
                            'WARNING: K3D nr of line segments is limited to 200.'
                        )
                        break
                    pts = ia.points()[ln_idx]
                    kobj = k3d.line(
                        pts.astype(numpy.float32),
                        color=_rgb2int(iap.GetColor()),
                        #                                    colors=kcols,
                        opacity=iap.GetOpacity(),
                        shader="thick",
                        # width=iap.GetLineWidth()*sqsize/1000,
                        name=name,
                    )

                    settings.notebook_plotter += kobj

    ####################################################################################
    elif settings.notebookBackend == 'panel' and hasattr(
            vp, 'window') and vp.window:

        import panel  # https://panel.pyviz.org/reference/panes/VTK.html
        vp.renderer.ResetCamera()
        settings.notebook_plotter = panel.pane.VTK(vp.window,
                                                   width=int(vp.size[0] / 1.5),
                                                   height=int(vp.size[1] / 2))

    ####################################################################################
    elif 'ipyvtk' in settings.notebookBackend and hasattr(
            vp, 'window') and vp.window:

        from ipyvtk_simple.viewer import ViewInteractiveWidget
        vp.renderer.ResetCamera()
        settings.notebook_plotter = ViewInteractiveWidget(vp.window)

    ####################################################################################
    elif '2d' in settings.notebookBackend.lower() and hasattr(
            vp, 'window') and vp.window:
        import PIL.Image
        try:
            import IPython
        except ImportError:
            raise Exception('IPython not available.')

        from vedo.io import screenshot
        settings.screeshotLargeImage = True
        nn = screenshot(returnNumpy=True, scale=settings.screeshotScale + 2)
        pil_img = PIL.Image.fromarray(nn)
        settings.notebook_plotter = IPython.display.display(pil_img)

    return settings.notebook_plotter
Esempio n. 3
0
    def __init__(
        self,
        csm,
        coordinate_systems: List[str] = None,
        data_sets: List[str] = None,
        colors: Dict[str, int] = None,
        reference_system: str = None,
        title: str = None,
        limits: types_limits = None,
        time: types_timeindex = None,
        time_ref: pd.Timestamp = None,
        show_data_labels: bool = True,
        show_labels: bool = True,
        show_origins: bool = True,
        show_traces: bool = True,
        show_vectors: bool = True,
        show_wireframe: bool = True,
    ):
        """Create a `CoordinateSystemManagerVisualizerK3D`.

        Parameters
        ----------
        csm : weldx.transformations.CoordinateSystemManager
            The `weldx.transformations.CoordinateSystemManager` instance that should be
            visualized
        coordinate_systems :
            The names of the coordinate systems that should be visualized. If ´None´ is
            provided, all systems are plotted
        data_sets :
            The names of data sets that should be visualized. If ´None´ is provided, all
            data is plotted
        colors :
            A mapping between a coordinate system name or a data set name and a color.
            The colors must be provided as 24 bit integer values that are divided into
            three 8 bit sections for the rgb values. For example `0xFF0000` for pure
            red.
            Each coordinate system or data set that does not have a mapping in this
            dictionary will get a default color assigned to it.
        reference_system :
            Name of the initial reference system. If `None` is provided, the root system
            of the `weldx.transformations.CoordinateSystemManager` instance will be used
        title :
            The title of the plot
        limits :
            The limits of the plotted volume
        time :
            The time steps that should be plotted initially
        time_ref :
            A reference timestamp that can be provided if the ``time`` parameter is a
            `pandas.TimedeltaIndex`
        show_data_labels :
            If `True`, the data labels will be shown initially
        show_labels  :
            If `True`, the coordinate system labels will be shown initially
        show_origins :
            If `True`, the coordinate systems' origins will be shown initially
        show_traces :
            If `True`, the coordinate systems' traces will be shown initially
        show_vectors :
            If `True`, the coordinate systems' axis vectors will be shown initially
        show_wireframe :
            If `True`, spatial data containing mesh data will be drawn as wireframe

        """
        if time is None:
            time = csm.time_union()
        if time is not None:
            csm = csm.interp_time(time=time, time_ref=time_ref)

        self._csm = csm.interp_time(time=time, time_ref=time_ref)
        self._current_time_index = 0

        if coordinate_systems is None:
            coordinate_systems = csm.coordinate_system_names
        if data_sets is None:
            data_sets = self._csm.data_names
        if reference_system is None:
            reference_system = self._csm.root_system_name
        self._current_reference_system = reference_system

        grid_auto_fit = True
        grid = (-1, -1, -1, 1, 1, 1)
        if limits is not None:
            grid_auto_fit = False
            if len(limits) == 1:
                grid = [limits[0][int(i / 3)] for i in range(6)]
            else:
                grid = [limits[i % 3][int(i / 3)] for i in range(6)]

        # create plot
        self._color_generator = color_generator_function()
        plot = k3d.plot(
            grid_auto_fit=grid_auto_fit,
            grid=grid,
        )
        self._lcs_vis = {
            lcs_name: CoordinateSystemVisualizerK3D(
                self._csm.get_cs(lcs_name, reference_system),
                plot,
                lcs_name,
                color=get_color(lcs_name, colors, self._color_generator),
                show_origin=show_origins,
                show_trace=show_traces,
                show_vectors=show_vectors,
            )
            for lcs_name in coordinate_systems
        }
        self._data_vis = {
            data_name: SpatialDataVisualizer(
                self._csm.get_data(data_name=data_name),
                data_name,
                self._csm.get_data_system_name(data_name=data_name),
                plot,
                color=get_color(data_name, colors, self._color_generator),
                show_wireframe=show_wireframe,
            )
            for data_name in data_sets
        }
        self._update_spatial_data()

        # create controls
        self._controls = self._create_controls(
            time,
            show_data_labels,
            show_labels,
            show_origins,
            show_traces,
            show_vectors,
            show_wireframe,
        )

        # add title
        self._title = None
        if title is not None:
            self._title = k3d.text2d(
                f"<b>{title}</b>",
                position=(0.5, 0),
                color=RGB_BLACK,
                is_html=True,
                size=1.5,
                reference_point="ct",
            )
            plot += self._title

        # add time info
        self._time = time
        self._time_ref = time_ref
        self._time_info = None
        if time is not None:
            self._time_info = k3d.text2d(
                f"<b>time:</b> {time[0]}",
                position=(0, 1),
                color=RGB_BLACK,
                is_html=True,
                size=1.0,
                reference_point="lb",
            )
            plot += self._time_info

        # display everything
        plot.display()
        display(self._controls)

        # workaround since using it inside the init method of the coordinate system
        # visualizer somehow causes the labels to be created twice with one version
        # being always visible
        self.show_data_labels(show_data_labels)
        self.show_labels(show_labels)