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
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
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)