def changeBackColor(self, c, acts=None, t=None, duration=None): """Gradually change backface color for the input list of meshes. An initial backface color should be set in advance.""" if self.bookingMode: acts, t, duration, rng = self._parse(acts, t, duration) col2 = getColor(c) for tt in rng: inputvalues = [] for a in acts: if a.GetBackfaceProperty(): col1 = a.backColor() r = linInterpolate(tt, [t, t + duration], [col1[0], col2[0]]) g = linInterpolate(tt, [t, t + duration], [col1[1], col2[1]]) b = linInterpolate(tt, [t, t + duration], [col1[2], col2[2]]) inputvalues.append((r, g, b)) else: inputvalues.append(None) self.events.append( (tt, self.changeBackColor, acts, inputvalues)) else: for i, a in enumerate(self._performers): a.backColor(self._inputvalues[i]) return self
def lineColor(self, lc=None): """Set/get color of mesh edges. Same as `lc()`.""" if lc is not None: if "ireframe" in self.GetProperty().GetRepresentationAsString(): self.GetProperty().EdgeVisibilityOff() self.color(lc) return self self.GetProperty().EdgeVisibilityOn() self.GetProperty().SetEdgeColor(colors.getColor(lc)) else: return self.GetProperty().GetEdgeColor() return self
def color(self, c=False): """ Set/get UGrid color. If None is passed as input, will use colors from active scalars. Same as `ugrid.c()`. """ if c is False: return np.array(self.GetProperty().GetColor()) elif c is None: self._mapper.ScalarVisibilityOn() return self self._mapper.ScalarVisibilityOff() cc = colors.getColor(c) self.GetProperty().SetColor(cc) if self.trail: self.trail.GetProperty().SetColor(cc) return self
def rotate(self, angle, center=(), scale=1, mirroring=False, bc='w', alpha=1): """ Rotate an image by an angle (anticlockwise). Parameters ---------- angle : float rotation angle in degrees. center: list center of rotation (x,y) in pixels. """ bounds = self.bounds() pc = [0, 0, 0] if center: pc[0] = center[0] pc[1] = center[1] else: pc[0] = (bounds[1] + bounds[0]) / 2.0 pc[1] = (bounds[3] + bounds[2]) / 2.0 pc[2] = (bounds[5] + bounds[4]) / 2.0 transform = vtk.vtkTransform() transform.Translate(pc) transform.RotateWXYZ(-angle, 0, 0, 1) transform.Scale(1 / scale, 1 / scale, 1) transform.Translate(-pc[0], -pc[1], -pc[2]) reslice = vtk.vtkImageReslice() reslice.SetMirror(mirroring) c = np.array(colors.getColor(bc)) * 255 reslice.SetBackgroundColor([c[0], c[1], c[2], alpha * 255]) reslice.SetInputData(self._data) reslice.SetResliceTransform(transform) reslice.SetOutputDimensionality(2) reslice.SetInterpolationModeToCubic() reslice.SetOutputSpacing(self._data.GetSpacing()) reslice.SetOutputOrigin(self._data.GetOrigin()) reslice.SetOutputExtent(self._data.GetExtent()) reslice.Update() return self._update(reslice.GetOutput())
def changeLineColor(self, c, acts=None, t=None, duration=None): """Gradually change line color of the mesh edges for the input list of meshes.""" if self.bookingMode: acts, t, duration, rng = self._parse(acts, t, duration) col2 = getColor(c) for tt in rng: inputvalues = [] for a in acts: col1 = a.lineColor() r = linInterpolate(tt, [t,t+duration], [col1[0], col2[0]]) g = linInterpolate(tt, [t,t+duration], [col1[1], col2[1]]) b = linInterpolate(tt, [t,t+duration], [col1[2], col2[2]]) inputvalues.append((r,g,b)) self.events.append((tt, self.changeLineColor, acts, inputvalues)) else: for i,a in enumerate(self._performers): a.lineColor(self._inputvalues[i]) return self
def make_palette(N, *colors): """Generate N colors starting from `color1` to `color2` by linear interpolation HSV in or RGB spaces. Adapted from vedo make_palette function :param int: N: number of output colors. :param colors: input colors, any number of colors with 0 < ncolors <= N is okay. """ N = int(N) N_input_colors = len(colors) if not N_input_colors: raise ValueError("No colors where passed to make_palette") if N_input_colors > N: raise ValueError( "More input colors than out colors (N) where passed to make_palette" ) if N_input_colors == N: return colors else: # Get how many colors for each pair of colors we are interpolating over fractions = [ N // N_input_colors + (1 if x < N % N_input_colors else 0) for x in range(N_input_colors) ] # Get pairs of colors cs = [np.array(getColor(col)) for col in colors] cs += [cs[-1]] output = [] for n, (c1, c2) in enumerate(zip(cs, cs[1:])): cols = [] for f in np.linspace(0, 1, fractions[n], endpoint=True): c = c1 * (1 - f) + c2 * f cols.append(c) output.extend(cols) return output
def RayCaster(volume): """ Generate a ``Plotter`` window for Volume rendering using ray casting. Returns the ``Plotter`` object. """ vp = settings.plotter_instance if not vp: vp = Plotter(axes=4, bg='bb') volumeProperty = volume.GetProperty() img = volume.imagedata() if volume.dimensions()[2] < 3: print("Error in raycaster: not enough depth", volume.dimensions()) return vp printc("GPU Ray-casting tool", c="b", invert=1) smin, smax = img.GetScalarRange() x0alpha = smin + (smax - smin) * 0.25 x1alpha = smin + (smax - smin) * 0.5 x2alpha = smin + (smax - smin) * 1.0 ############################## color map slider # Create transfer mapping scalar value to color cmaps = [ "jet", "viridis", "bone", "hot", "plasma", "winter", "cool", "gist_earth", "coolwarm", "tab10", ] cols_cmaps = [] for cm in cmaps: cols = colorMap(range(0, 21), cm, 0, 20) # sample 20 colors cols_cmaps.append(cols) Ncols = len(cmaps) csl = (0.9, 0.9, 0.9) if sum(getColor(vp.renderer.GetBackground())) > 1.5: csl = (0.1, 0.1, 0.1) def sliderColorMap(widget, event): sliderRep = widget.GetRepresentation() k = int(sliderRep.GetValue()) sliderRep.SetTitleText(cmaps[k]) volume.color(cmaps[k]) w1 = vp.addSlider2D( sliderColorMap, 0, Ncols - 1, value=0, showValue=0, title=cmaps[0], c=csl, pos=[(0.8, 0.05), (0.965, 0.05)], ) w1.GetRepresentation().SetTitleHeight(0.018) ############################## alpha sliders # Create transfer mapping scalar value to opacity opacityTransferFunction = volumeProperty.GetScalarOpacity() def setOTF(): opacityTransferFunction.RemoveAllPoints() opacityTransferFunction.AddPoint(smin, 0.0) opacityTransferFunction.AddPoint(smin + (smax - smin) * 0.1, 0.0) opacityTransferFunction.AddPoint(x0alpha, _alphaslider0) opacityTransferFunction.AddPoint(x1alpha, _alphaslider1) opacityTransferFunction.AddPoint(x2alpha, _alphaslider2) setOTF() def sliderA0(widget, event): global _alphaslider0 _alphaslider0 = widget.GetRepresentation().GetValue() setOTF() vp.addSlider2D(sliderA0, 0, 1, value=_alphaslider0, pos=[(0.84, 0.1), (0.84, 0.26)], c=csl, showValue=0) def sliderA1(widget, event): global _alphaslider1 _alphaslider1 = widget.GetRepresentation().GetValue() setOTF() vp.addSlider2D(sliderA1, 0, 1, value=_alphaslider1, pos=[(0.89, 0.1), (0.89, 0.26)], c=csl, showValue=0) def sliderA2(widget, event): global _alphaslider2 _alphaslider2 = widget.GetRepresentation().GetValue() setOTF() w2 = vp.addSlider2D(sliderA2, 0, 1, value=_alphaslider2, pos=[(0.96, 0.1), (0.96, 0.26)], c=csl, showValue=0, title="Opacity levels") w2.GetRepresentation().SetTitleHeight(0.016) # add a button def buttonfuncMode(): s = volume.mode() snew = (s + 1) % 2 volume.mode(snew) bum.switch() bum = vp.addButton( buttonfuncMode, pos=(0.7, 0.035), states=["composite", "max proj."], c=["bb", "gray"], bc=["gray", "bb"], # colors of states font="", size=16, bold=0, italic=False, ) bum.status(volume.mode()) def CheckAbort(obj, event): if obj.GetEventPending() != 0: obj.SetAbortRender(1) vp.window.AddObserver("AbortCheckEvent", CheckAbort) # add histogram of scalar plot = cornerHistogram( volume.getPointArray(), bins=25, logscale=1, c=(.7, .7, .7), bg=(.7, .7, .7), pos=(0.78, 0.065), lines=True, dots=False, ) # xbins = np.linspace(smin, smax, 25) # yvals = volume.histogram(bins=25, logscale=1) # plot = cornerPlot(np.c_[xbins, yvals], # c=(.7,.7,.7), bg=(.7,.7,.7), pos=(0.78, 0.065), s=0.4, # lines=True, dots=False, # ) plot.GetPosition2Coordinate().SetValue(0.197, 0.20, 0) plot.GetXAxisActor2D().SetFontFactor(0.7) plot.GetProperty().SetOpacity(0.5) vp.add([plot, volume]) return vp
def text( self, txt, pos=(0, 0, 0), s=1, c=None, alpha=1, bg=None, font="Theemim", dpi=500, justify="bottom-left", ): """Build an image from a string.""" 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.3, 0.3, 0.3) r = vtk.vtkTextRenderer() img = vtk.vtkImageData() tp = vtk.vtkTextProperty() tp.BoldOff() tp.SetColor(colors.getColor(c)) tp.SetJustificationToLeft() if "top" in justify: tp.SetVerticalJustificationToTop() if "bottom" in justify: tp.SetVerticalJustificationToBottom() if "cent" in justify: tp.SetVerticalJustificationToCentered() tp.SetJustificationToCentered() if "left" in justify: tp.SetJustificationToLeft() if "right" in justify: tp.SetJustificationToRight() 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) 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() #GetConstrainedFontSize (const vtkUnicodeString &str, # vtkTextProperty *tprop, int targetWidth, int targetHeight, int dpi) fs = r.GetConstrainedFontSize(txt, tp, 900, 1000, dpi) tp.SetFontSize(fs) r.RenderString(tp, txt, img, [1, 1], dpi) # RenderString (vtkTextProperty *tprop, const vtkStdString &str, # vtkImageData *data, int textDims[2], int dpi, int backend=Default) self.SetInputData(img) self.GetMapper().Modified() self.SetPosition(pos) x0, x1 = self.xbounds() if x1 != x0: sc = s / (x1 - x0) self.SetScale(sc, sc, sc) return self
def warp(self, sourcePts=(), targetPts=(), transform=None, sigma=1, mirroring=False, bc='w', alpha=1): """ Warp an image using thin-plate splines. Parameters ---------- sourcePts : list, optional source points. targetPts : list, optional target points. transform : TYPE, optional a vtkTransform object can be supplied. The default is None. sigma : float, optional stiffness of the interpolation. The default is 1. mirroring : TYPE, optional fill the margins with a reflection of the original image. The default is False. bc : TYPE, optional fill the margins with a solid color. The default is 'w'. alpha : TYPE, optional opacity of the filled margins. The default is 1. """ if transform is None: # source and target must be filled transform = vtk.vtkThinPlateSplineTransform() transform.SetBasisToR2LogR() if isinstance(sourcePts, vedo.Points): sourcePts = sourcePts.points() if isinstance(targetPts, vedo.Points): targetPts = targetPts.points() ns = len(sourcePts) nt = len(targetPts) if ns != nt: colors.printc("Error in picture.warp(): #source != #target points", ns, nt, c='r') raise RuntimeError() ptsou = vtk.vtkPoints() ptsou.SetNumberOfPoints(ns) pttar = vtk.vtkPoints() pttar.SetNumberOfPoints(nt) for i in range(ns): p = sourcePts[i] ptsou.SetPoint(i, [p[0],p[1],0]) p = targetPts[i] pttar.SetPoint(i, [p[0],p[1],0]) transform.SetSigma(sigma) transform.SetSourceLandmarks(pttar) transform.SetTargetLandmarks(ptsou) else: # ignore source and target pass reslice = vtk.vtkImageReslice() reslice.SetInputData(self._data) reslice.SetOutputDimensionality(2) reslice.SetResliceTransform(transform) reslice.SetInterpolationModeToCubic() reslice.SetMirror(mirroring) c = np.array(colors.getColor(bc))*255 reslice.SetBackgroundColor([c[0],c[1],c[2], alpha*255]) reslice.Update() self.transform = transform return self._update(reslice.GetOutput())
def draw_scene(args): nfiles = len(args.files) if nfiles == 0: printc("No input files.", c='r') return humansort(args.files) wsize = "auto" if args.full_screen: wsize = "full" if args.ray_cast_mode: if args.background == "": args.background = "bb" if args.background == "": args.background = "white" if args.background_grad: args.background_grad = getColor(args.background_grad) if nfiles == 1 and args.files[0].endswith(".gif"): ###can be improved frames = load(args.files[0]) applications.Browser(frames).show(bg=args.background, bg2=args.background_grad) return ########################################################## if args.scrolling_mode: args.multirenderer_mode = False N = None if args.multirenderer_mode: if nfiles < 201: N = nfiles if nfiles > 200: printc("Warning: option '-n' allows a maximum of 200 files", c=1) printc(" you are trying to load ", nfiles, " files.\n", c=1) N = 200 vp = Plotter(size=wsize, N=N, bg=args.background, bg2=args.background_grad) settings.immediateRendering = False vp.axes = args.axes_type for i in range(N): vp.addHoverLegend(at=i) if args.axes_type == 4 or args.axes_type == 5: vp.axes = 0 else: N = nfiles vp = Plotter(size=wsize, bg=args.background, bg2=args.background_grad) vp.axes = args.axes_type vp.addHoverLegend() vp.sharecam = not args.no_camera_share wire = False if args.wireframe: wire = True ########################################################## # special case of SLC/TIFF volumes with -g option if args.ray_cast_mode: # print('DEBUG special case of SLC/TIFF volumes with -g option') vol = io.load(args.files[0], force=args.reload) if not isinstance(vol, Volume): printc("Type Error: expected a Volume but loaded", type(vol), 'object.', c=1) return sp = vol.spacing() vol.spacing([ sp[0] * args.x_spacing, sp[1] * args.y_spacing, sp[2] * args.z_spacing ]) vol.mode(int(args.mode)).color(args.cmap).jittering(True) # if args.lighting !='default': vol.lighting(args.lighting).jittering(True) vp = applications.RayCastPlotter(vol) vp.show(viewup="z", interactive=True) vp.sliders[0][0].SetEnabled(False) vp.sliders[1][0].SetEnabled(False) vp.sliders[2][0].SetEnabled(False) return ########################################################## # special case of SLC/TIFF/DICOM volumes with --slicer option elif args.slicer: # print('DEBUG special case of SLC/TIFF/DICOM volumes with --slicer option') useSlider3D = False if args.axes_type == 4: args.axes_type = 1 elif args.axes_type == 3: args.axes_type = 1 useSlider3D = True vol = io.load(args.files[0], force=args.reload) sp = vol.spacing() vol.spacing([ sp[0] * args.x_spacing, sp[1] * args.y_spacing, sp[2] * args.z_spacing ]) settings.plotter_instance = None # reset plt = applications.SlicerPlotter( vol, bg='white', bg2='lb', useSlider3D=useSlider3D, cmaps=[args.cmap, "Spectral_r", "hot_r", "bone_r", "gist_ncar_r"], alpha=args.alpha, axes=args.axes_type, clamp=True, size=(1000, 800), ) plt.show() return ######################################################################## elif args.edit: # print('edit mode for meshes and pointclouds') settings.plotter_instance = None # reset settings.useParallelProjection = True try: m = Mesh(args.files[0], alpha=args.alpha / 2, c=args.color) except AttributeError: printc( "In edit mode, input file must be a point cloud or polygonal mesh. Exit.", c='r') return vp = applications.FreeHandCutPlotter(m, splined=True) vp.addHoverLegend() if not args.background_grad: args.background_grad = None vp.start(axes=1, bg=args.background, bg2=args.background_grad) ######################################################################## elif args.slicer2d: # print('DEBUG special case of SLC/TIFF/DICOM volumes with --slicer2d option') vol = io.load(args.files[0], force=args.reload) if not vol: return vol.cmap('bone_r') sp = vol.spacing() vol.spacing([ sp[0] * args.x_spacing, sp[1] * args.y_spacing, sp[2] * args.z_spacing ]) settings.plotter_instance = None # reset plt = applications.Slicer2d(vol) plt.interactor.Start() return ######################################################################## # normal mode for single VOXEL file with Isosurface Slider or LEGO mode elif nfiles == 1 and (".slc" in args.files[0].lower() or ".vti" in args.files[0].lower() or ".tif" in args.files[0].lower() or ".mhd" in args.files[0].lower() or ".nrrd" in args.files[0].lower() or ".dem" in args.files[0].lower()): # print('DEBUG normal mode for single VOXEL file with Isosurface Slider or LEGO mode') vol = io.load(args.files[0], force=args.reload) sp = vol.spacing() vol.spacing([ sp[0] * args.x_spacing, sp[1] * args.y_spacing, sp[2] * args.z_spacing ]) if not args.color: args.color = 'gold' vp = applications.IsosurfaceBrowser(vol, lego=args.lego, c=args.color, cmap=args.cmap, delayed=args.lego) vp.show(zoom=args.zoom, viewup="z") return ######################################################################## # NORMAL mode for single or multiple files, or multiren mode, or numpy scene elif nfiles == 1 or (not args.scrolling_mode): # print('DEBUG NORMAL mode for single or multiple files, or multiren mode') interactor_mode = 0 if args.image: interactor_mode = 'image' ########################################################## # loading a full scene if ".npy" in args.files[0] or ".npz" in args.files[0] and nfiles == 1: objct = io.load(args.files[0], force=args.reload) if "Plotter" in str(type(objct)): # loading a full scene objct.show(mode=interactor_mode) return else: # loading a set of meshes vp.show(objct, mode=interactor_mode) return ######################################################### ds = 0 actors = [] for i in range(N): f = args.files[i] colb = args.color if args.color is None and N > 1: colb = i actor = load(f, force=args.reload) if isinstance(actor, (TetMesh, UGrid)): actor = actor.tomesh().shrink(0.975).c(colb).alpha(args.alpha) if isinstance(actor, Mesh): actors.append(actor) actor.c(colb).alpha(args.alpha).wireframe(wire).lighting( args.lighting) if args.flat: actor.flat() else: actor.phong() if i == 0 and args.texture_file: actor.texture(args.texture_file) if args.point_size > 0: try: actor.GetProperty().SetPointSize(args.point_size) actor.GetProperty().SetRepresentationToPoints() except AttributeError: pass if args.showedges: try: actor.GetProperty().SetEdgeVisibility(1) actor.GetProperty().SetLineWidth(0.1) actor.GetProperty().SetRepresentationToSurface() except AttributeError: pass else: actors.append(actor) if args.multirenderer_mode: try: ds = actor.diagonalSize() * 3 vp.camera.SetClippingRange(0, ds) vp.show(actor, at=i, interactive=False, zoom=args.zoom, mode=interactor_mode) vp.actors = actors except AttributeError: # wildcards in quotes make glob return actor as a list :( printc( "Please do not use wildcards within single or double quotes!", c='r') if args.multirenderer_mode: vp.interactor.Start() else: # scene is empty if all(a is None for a in actors): printc("..could not load file(s). Quit.", c='r') return vp.show(actors, interactive=True, zoom=args.zoom, mode=interactor_mode) return ######################################################################## # scrolling mode -s else: #print("DEBUG simple browser mode -s") if vp.axes == 4: vp.axes = 1 acts = vp.load(args.files, force=args.reload) for a in acts: if hasattr(a, 'c'): #Picture doesnt have it a.c(args.color) a.alpha(args.alpha) applications.Browser(acts) vp.show(interactive=True, zoom=args.zoom)
def exe_eog(args): # print("EOG emulator") settings.immediateRendering = False settings.useParallelProjection = True settings.enableDefaultMouseCallbacks = False settings.enableDefaultKeyboardCallbacks = False if args.background == "": args.background = "white" if args.background_grad: args.background_grad = getColor(args.background_grad) files = [] for s in sys.argv: if '--' in s or s.endswith('.py') or s.endswith('vedo'): continue if s.endswith('.gif'): continue files.append(s) def vfunc(event): # print(event.keyPressed) for p in pics: if event.keyPressed == "r": p.window(win).level(lev) elif event.keyPressed == "Up": p.level(p.level() + 10) elif event.keyPressed == "Down": p.level(p.level() - 10) if event.keyPressed == "Right": p.window(p.window() + 10) elif event.keyPressed == "Down": p.window(p.window() - 10) elif event.keyPressed == "m": p.mirror() elif event.keyPressed == "t": p.rotate(90) elif event.keyPressed == "k": p.enhance() elif event.keyPressed == "s": p.smooth(sigma=1) elif event.keyPressed == "S": ahl = plt.hoverLegends[-1] plt.remove(ahl) plt.screenshot() # writer printc("Picture saved as screenshot.png") plt.add(ahl, render=False) return elif event.keyPressed == "h": printc('---------------------------------------------') printc('Press:') printc(' up/down to modify level (or drag mouse)') printc(' left/right to modify window') printc(' m to mirror image') printc(' t to rotate image by 90 deg') printc(' k to enhance b&w image') printc(' s to apply gaussian smoothing') printc(' S to save image as png') printc('---------------------------------------------') plt.render() pics = load(files) if isinstance(pics, Picture): pics = [pics] if pics is None: return n = len(pics) pic = pics[0] if pic is None: printc("Could not load image.", c='r') return lev, win = pic.level(), pic.window() if n > 1: plt = Plotter(N=n, sharecam=True, bg=args.background, bg2=args.background_grad) plt.addCallback('key press', vfunc) for i in range(n): p = pics[i].pickable(True) pos = [-p.shape[0] / 2, -p.shape[1] / 2, 0] p.pos(pos) plt.addHoverLegend(at=i, c='k8', bg='k2', alpha=0.4) plt.show(p, axes=0, at=i, mode='image') plt.show(interactive=False) plt.resetCamera(xypad=0.05) plt.interactor.Start() else: shape = pic.shape if shape[0] > 1500: shape[1] = shape[1] / shape[0] * 1500 shape[0] = 1500 if shape[1] > 1200: shape[0] = shape[0] / shape[1] * 1200 shape[1] = 1200 plt = Plotter(title=files[0], size=shape, bg=args.background, bg2=args.background_grad) plt.addCallback('key press', vfunc) plt.addHoverLegend(c='k8', bg='k2', alpha=0.4) plt.show(pic, mode='image', interactive=False) plt.resetCamera(xypad=0.0) plt.interactor.Start() plt.close()
def _run(self): tips() args.files = list(self.filenames) if self.colorCB.get() == "by scalar": args.color = None else: if self.colorCB.get() == 'red': args.color = 'crimson' elif self.colorCB.get() == 'green': args.color = 'limegreen' elif self.colorCB.get() == 'blue': args.color = 'darkcyan' else: args.color = self.colorCB.get() args.alpha = self.alphaCB.get() args.wireframe = False args.showedges = False args.point_size = 0 if self.surfmodeCB.get() == 'point cloud': args.point_size = 2 elif self.surfmodeCB.get() == 'wireframe': args.wireframe = True elif self.surfmodeCB.get() == 'surf. & edges': args.showedges = True else: pass # normal surface mode args.lighting = self.lightCB.get() args.flat = self.flat.get() args.no_camera_share = self.noshare.get() args.background = self.bgcolorCB.get() args.background_grad = None if self.background_grad.get(): b = getColor(args.background) args.background_grad = (b[0] / 1.8, b[1] / 1.8, b[2] / 1.8) args.multirenderer_mode = False args.scrolling_mode = False if self.schememodeCB.get() == "n sync-ed renderers": args.multirenderer_mode = True elif self.schememodeCB.get() == "mesh browser": args.scrolling_mode = True args.ray_cast_mode = False args.lego = False args.slicer = False args.slicer2d = False args.lego = False args.mode = 0 if self.modeCB.get() == "composite": args.ray_cast_mode = True args.mode = 0 elif self.modeCB.get() == "maximum proj": args.ray_cast_mode = True args.mode = 1 elif self.modeCB.get() == "slicer": args.slicer = True elif self.modeCB.get() == "slicer2d": args.slicer2d = True elif self.modeCB.get() == "lego": args.lego = True args.x_spacing = 1 args.y_spacing = 1 args.z_spacing = 1 if self.xspacing.get() != '1.0': args.x_spacing = float(self.xspacing.get()) if self.yspacing.get() != '1.0': args.y_spacing = float(self.yspacing.get()) if self.zspacing.get() != '1.0': args.z_spacing = float(self.zspacing.get()) draw_scene(args) if os.name == "nt": exit() if settings.plotter_instance: settings.plotter_instance.close()
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance if zoom == 'tight': zoom=1 # disable it 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=settings.k3dMenuVisibility, height=settings.k3dPlotHeight, antialias=settings.k3dAntialias, ) # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = settings.k3dLighting # set k3d camera settings.notebook_plotter.camera_auto_fit = settings.k3dCameraAutoFit settings.notebook_plotter.grid_auto_fit = settings.k3dGridAutoFit settings.notebook_plotter.axes_helper = settings.k3dAxesHelper 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.pointdata[0] 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): # print('Points', ia.name, ia.N()) kcols=[] if color_attribute is not None: scals = utils.vtk2numpy(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=settings.k3dPointShader, point_size=iap.GetPointSize(), name=name, ) settings.notebook_plotter += kobj #####################################################################Lines 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 = utils.vtk2numpy(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()), opacity=iap.GetOpacity(), shader=settings.k3dLineShader, # 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 ipyvtklink.viewer import ViewInteractiveWidget vp.renderer.ResetCamera() settings.notebook_plotter = ViewInteractiveWidget(vp.window) #################################################################################### elif 'ipygany' in settings.notebookBackend: from ipygany import PolyMesh, Scene, IsoColor, RGB, Component from ipygany import Alpha, ColorBar, colormaps, PointCloud from ipywidgets import FloatRangeSlider, Dropdown, VBox, AppLayout, jslink bgcol = colors.rgb2hex(colors.getColor(vp.backgrcol)) actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vedo.Assembly): #unpack assemblies assacts = ia.unpack() for ja in assacts: if isinstance(ja, vedo.Assembly): actors2show2 += ja.unpack() else: actors2show2.append(ja) else: actors2show2.append(ia) pmeshes = [] colorbar = None for obj in actors2show2: # print("ipygany processing:", [obj], obj.name) if isinstance(obj, vedo.shapes.Line): lg = obj.diagonalSize()/1000 * obj.GetProperty().GetLineWidth() vmesh = vedo.shapes.Tube(obj.points(), r=lg, res=4).triangulate() vmesh.c(obj.c()) faces = vmesh.faces() # todo: Lines elif isinstance(obj, Mesh): vmesh = obj.triangulate() faces = vmesh.faces() elif isinstance(obj, Points): vmesh = obj faces = [] elif isinstance(obj, Volume): vmesh = obj.isosurface() faces = vmesh.faces() elif isinstance(obj, vedo.TetMesh): vmesh = obj.tomesh(fill=False) faces = vmesh.faces() else: print("ipygany backend: cannot process object type", [obj]) continue vertices = vmesh.points() scals = vmesh.inputdata().GetPointData().GetScalars() if scals and not colorbar: # there is an active array, only pick the first aname = scals.GetName() arr = vmesh.pointdata[aname] parr = Component(name=aname, array=arr) if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces, data={aname: [parr]}) else: pmesh = PointCloud(vertices=vertices, data={aname: [parr]}) rng = scals.GetRange() colored_pmesh = IsoColor(pmesh, input=aname, min=rng[0], max=rng[1]) if obj.scalarbar: colorbar = ColorBar(colored_pmesh) colormap_slider_range = FloatRangeSlider(value=rng, min=rng[0], max=rng[1], step=(rng[1] - rng[0]) / 100.) jslink((colored_pmesh, 'range'), (colormap_slider_range, 'value')) colormap = Dropdown( options=colormaps, description='Colormap:' ) jslink((colored_pmesh, 'colormap'), (colormap, 'index')) else: if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces) else: pmesh = PointCloud(vertices=vertices) if vmesh.alpha() < 1: colored_pmesh = Alpha(RGB(pmesh, input=tuple(vmesh.color())), input=vmesh.alpha()) else: colored_pmesh = RGB(pmesh, input=tuple(vmesh.color())) pmeshes.append(colored_pmesh) if colorbar: scene = AppLayout( left_sidebar=Scene(pmeshes, background_color=bgcol), right_sidebar=VBox((colormap_slider_range, #not working colorbar, colormap)), pane_widths=[2, 0, 1], ) else: scene = Scene(pmeshes, background_color=bgcol) settings.notebook_plotter = scene #################################################################################### 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
""" Show a cube for each available color name """ print(__doc__) from vedo import Cube, Text2D, show from vedo.colors import colors, getColor from operator import itemgetter # sorting by hex color code: sorted_colors = sorted(colors.items(), key=itemgetter(1)) # or by name: # sorted_colors = sorted(colors.items(), key=itemgetter(0)) cbs = [] for i, sc in enumerate(sorted_colors): cname = sc[0] rgb = getColor(cname) cb = Cube(c=rgb) tname = Text2D(cname, pos=3) cbs.append([tname, cb]) print("click on any cube and press i") show(cbs, N=len(sorted_colors), azimuth=.2, size='fullscreen')