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