def show_vedo_mesh_old(verts, faces, filling_factors): start = time.time() mesh = Mesh([verts, faces]) mesh.backColor('blue').lineColor('white').lineWidth(0) # retrieve them as numpy arrays # printc('points():\n', mesh.points(), c=3) # printc('faces(): \n', mesh.faces(), c=3) # show(mesh, labs, __doc__, viewup='z', axes=1) colors = [] all_cells = mesh.faces() for i in range(mesh.NCells()): points = all_cells[i] ff_sum = 0 for p in points: ff_sum += filling_factors[p] c = int((ff_sum / 3) * 200) colors.append((c, 0, 0)) mesh.cellIndividualColors(colors) # show(mesh, __doc__, viewup='z', interactive=False, camera={'pos': (-1, -1, 2)}) # isometric: 2 2 2 plotter = Plotter(size=(1024, 1024), interactive=False) plotter += mesh plotter += __doc__ plotter.show(viewup='z', camera={'pos': (-1, -1, 2)}) screenshot() end = time.time() print(f"Calculation took {end - start} seconds.")
def IsosurfaceBrowser(volume, c=None, alpha=1, lego=False, cmap='hot', pos=None): """ Generate a ``Plotter`` window for Volume isosurfacing using a slider. Returns the ``Plotter`` object. """ vp = settings.plotter_instance if not vp: vp = Plotter(axes=4, bg='w', title="Isosurface Browser") scrange = volume.scalarRange() threshold = (scrange[1] - scrange[0]) / 3.0 + scrange[0] if lego: sliderpos = ((0.79, 0.035), (0.975, 0.035)) slidertitle = "" showval = False mesh = volume.legosurface(vmin=threshold, cmap=cmap).alpha(alpha) mesh.addScalarBar(horizontal=True) else: sliderpos = 4 slidertitle = "threshold" showval = True mesh = volume.isosurface(threshold) mesh.color(c).alpha(alpha) if pos is not None: sliderpos = pos vp.actors = [mesh] + vp.actors ############################## threshold slider bacts = dict() def sliderThres(widget, event): prevact = vp.actors[0] wval = widget.GetRepresentation().GetValue() wval_2 = precision(wval, 2) if wval_2 in bacts.keys(): # reusing the already available mesh mesh = bacts[wval_2] else: # else generate it if lego: mesh = volume.legosurface(vmin=wval, cmap=cmap) else: mesh = volume.isosurface(threshold=wval).color(c).alpha(alpha) bacts.update({wval_2: mesh}) # store it vp.renderer.RemoveActor(prevact) vp.renderer.AddActor(mesh) vp.actors[0] = mesh dr = scrange[1] - scrange[0] vp.addSlider2D( sliderThres, scrange[0] + 0.02 * dr, scrange[1] - 0.02 * dr, value=threshold, pos=sliderpos, title=slidertitle, showValue=showval) return vp
def Browser( meshes, sliderpos=((0.55, 0.07), (0.96, 0.07)), c=None, prefix="", # extras=(), #Not working ): """ Generate a ``Plotter`` window to browse a list of objects using a slider. Returns the ``Plotter`` object. """ vp = settings.plotter_instance if not vp: vp = Plotter(axes=1, bg='white', title="Browser") vp.actors = meshes # define the slider def sliderfunc(widget, event=None): k = int(widget.GetRepresentation().GetValue()) ak = vp.actors[k] for a in vp.actors: if a == ak: a.on() else: a.off() tx = str(k) if ak.filename: tx = ak.filename.split("/")[-1] tx = tx.split("\\")[-1] # windows os elif ak.name: tx = ak.name widget.GetRepresentation().SetTitleText(prefix + tx) # printc("Browser", c="y", invert=1, end="") # printc(" loaded", len(meshes), "objects", c="y", bold=False) wid = vp.addSlider2D(sliderfunc, 0.5, len(meshes) - 0.5, pos=sliderpos, font='courier', c=c, showValue=False) wid.GetRepresentation().SetTitleHeight(0.020) sliderfunc(wid) # init call # for e in extras: # vp.add(extras, render=False) return vp
def __init__( self, mesh, splined=True, font="Bongas", alpha=0.9, lw=4, lc="red5", pc="red4", c="green3", tc="k9", tol=0.008, ): if not isinstance(mesh, Points): printc("FreeHandCutPlotter input must be Points or Mesh.", c='r') raise RuntimeError() Plotter.__init__(self, title="Free-hand mesh cutter") self.mesh = mesh self.mesh_prev = mesh self.splined = splined self.linecolor = lc self.linewidth = lw self.pointcolor = pc self.color = c self.alpha = alpha self.msg = "Right-click and move to draw line\n" self.msg += "Second right-click to stop drawing\n" self.msg += "Press L to extract largest surface\n" self.msg += " z/Z to cut mesh (s to save)\n" self.msg += " c to clear points, u to undo" self.txt2d = Text2D(self.msg, pos='top-left', font=font, s=0.9) self.txt2d.c(tc).background(c, alpha).frame() self.idkeypress = self.addCallback('KeyPress', self._onKeyPress) self.idrightclck = self.addCallback('RightButton', self._onRightClick) self.idmousemove = self.addCallback('MouseMove', self._onMouseMove) self.drawmode = False self.tol = tol # tolerance of point distance self.cpoints = [] self.points = None self.spline = None self.jline = None self.topline = None self.top_pts = []
def __init__(self, totalDuration=None, timeResolution=0.02, showProgressBar=True, videoFileName='animation.mp4', videoFPS=12): Plotter.__init__(self) self.resetcam = True self.events = [] self.timeResolution = timeResolution self.totalDuration = totalDuration self.showProgressBar = showProgressBar self.videoFileName = videoFileName self.videoFPS = videoFPS self.bookingMode = True self._inputvalues = [] self._performers = [] self._lastT = None self._lastDuration = None self._lastActs = None self.eps = 0.00001
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 Slicer( volume, alpha=1, cmaps=('gist_ncar_r', "hot_r", "bone_r", "jet", "Spectral_r"), map2cells=False, # buggy clamp=True, useSlider3D=False, size=(850, 700), screensize="auto", title="", bg="white", bg2="lightblue", axes=7, showHisto=True, showIcon=True, draggable=False, verbose=True, ): """ Generate a ``Plotter`` window with slicing planes for the input Volume. Returns the ``Plotter`` object. :param float alpha: transparency of the slicing planes :param list cmaps: list of color maps names to cycle when clicking button :param bool map2cells: scalars are mapped to cells, not intepolated. :param bool clamp: clamp scalar to reduce the effect of tails in color mapping :param bool useSlider3D: show sliders attached along the axes :param list size: rendering window size in pixels :param list screensize: size of the screen can be specified :param str title: window title :param bg: background color :param bg2: background gradient color :param int axes: axis type number :param bool showHisto: show histogram on bottom left :param bool showIcon: show a small 3D rendering icon of the volume :param bool draggable: make the icon draggable """ global _cmap_slicer if verbose: printc("Slicer tool", invert=1, c="m") ################################ vp = Plotter( bg=bg, bg2=bg2, size=size, screensize=screensize, title=title, interactive=False, ) ################################ box = volume.box().wireframe().alpha(0) vp.show(box, viewup="z", axes=axes) if showIcon: vp.addInset(volume, pos=(.85, .85), size=0.15, c='w', draggable=draggable) # inits la, ld = 0.7, 0.3 #ambient, diffuse dims = volume.dimensions() data = volume.getPointArray() rmin, rmax = volume.imagedata().GetScalarRange() if clamp: hdata, edg = np.histogram(data, bins=50) logdata = np.log(hdata + 1) # mean of the logscale plot meanlog = np.sum(np.multiply(edg[:-1], logdata)) / np.sum(logdata) rmax = min(rmax, meanlog + (meanlog - rmin) * 0.9) rmin = max(rmin, meanlog - (rmax - meanlog) * 0.9) if verbose: printc('scalar range clamped to: (' + precision(rmin, 3) + ', ' + precision(rmax, 3) + ')', c='m', bold=0) _cmap_slicer = cmaps[0] visibles = [None, None, None] msh = volume.zSlice(int(dims[2] / 2)) msh.alpha(alpha).lighting('', la, ld, 0) msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax) if map2cells: msh.mapPointsToCells() vp.renderer.AddActor(msh) visibles[2] = msh addScalarBar(msh, pos=(0.04, 0.0), horizontal=True, titleFontSize=0) def sliderfunc_x(widget, event): i = int(widget.GetRepresentation().GetValue()) msh = volume.xSlice(i).alpha(alpha).lighting('', la, ld, 0) msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax) if map2cells: msh.mapPointsToCells() vp.renderer.RemoveActor(visibles[0]) if i and i < dims[0]: vp.renderer.AddActor(msh) visibles[0] = msh def sliderfunc_y(widget, event): i = int(widget.GetRepresentation().GetValue()) msh = volume.ySlice(i).alpha(alpha).lighting('', la, ld, 0) msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax) if map2cells: msh.mapPointsToCells() vp.renderer.RemoveActor(visibles[1]) if i and i < dims[1]: vp.renderer.AddActor(msh) visibles[1] = msh def sliderfunc_z(widget, event): i = int(widget.GetRepresentation().GetValue()) msh = volume.zSlice(i).alpha(alpha).lighting('', la, ld, 0) msh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax) if map2cells: msh.mapPointsToCells() vp.renderer.RemoveActor(visibles[2]) if i and i < dims[2]: vp.renderer.AddActor(msh) visibles[2] = msh cx, cy, cz, ch = 'dr', 'dg', 'db', (0.3, 0.3, 0.3) if np.sum(vp.renderer.GetBackground()) < 1.5: cx, cy, cz = 'lr', 'lg', 'lb' ch = (0.8, 0.8, 0.8) if not useSlider3D: vp.addSlider2D(sliderfunc_x, 0, dims[0], title='X', titleSize=0.5, pos=[(0.8, 0.12), (0.95, 0.12)], showValue=False, c=cx) vp.addSlider2D(sliderfunc_y, 0, dims[1], title='Y', titleSize=0.5, pos=[(0.8, 0.08), (0.95, 0.08)], showValue=False, c=cy) vp.addSlider2D(sliderfunc_z, 0, dims[2], title='Z', titleSize=0.6, value=int(dims[2] / 2), pos=[(0.8, 0.04), (0.95, 0.04)], showValue=False, c=cz) else: # 3d sliders attached to the axes bounds bs = box.bounds() vp.addSlider3D( sliderfunc_x, pos1=(bs[0], bs[2], bs[4]), pos2=(bs[1], bs[2], bs[4]), xmin=0, xmax=dims[0], t=box.diagonalSize() / mag(box.xbounds()) * 0.6, c=cx, showValue=False, ) vp.addSlider3D( sliderfunc_y, pos1=(bs[1], bs[2], bs[4]), pos2=(bs[1], bs[3], bs[4]), xmin=0, xmax=dims[1], t=box.diagonalSize() / mag(box.ybounds()) * 0.6, c=cy, showValue=False, ) vp.addSlider3D( sliderfunc_z, pos1=(bs[0], bs[2], bs[4]), pos2=(bs[0], bs[2], bs[5]), xmin=0, xmax=dims[2], value=int(dims[2] / 2), t=box.diagonalSize() / mag(box.zbounds()) * 0.6, c=cz, showValue=False, ) ################# def buttonfunc(): global _cmap_slicer bu.switch() _cmap_slicer = bu.status() for mesh in visibles: if mesh: mesh.cmap(_cmap_slicer, vmin=rmin, vmax=rmax) if map2cells: mesh.mapPointsToCells() vp.renderer.RemoveActor(mesh.scalarbar) mesh.scalarbar = addScalarBar(mesh, pos=(0.04, 0.0), horizontal=True, titleFontSize=0) vp.renderer.AddActor(mesh.scalarbar) bu = vp.addButton( buttonfunc, pos=(0.27, 0.005), states=cmaps, c=["db"] * len(cmaps), bc=["lb"] * len(cmaps), # colors of states size=14, bold=True, ) ################# hist = None if showHisto: hist = cornerHistogram(data, s=0.2, bins=25, logscale=1, pos=(0.02, 0.02), c=ch, bg=ch, alpha=0.7) comment = None if verbose: comment = Text2D( "Use sliders to slice volume\nClick button to change colormap", font='', s=0.8) vp.show(msh, hist, comment, interactive=False) vp.interactive = True if verbose: printc("Press button to cycle through color maps,", c="m") printc("Use sliders to select the slicing planes.", c="m") return vp
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()