def __init__(self): self.wall = vplt.load( absfilepath("data/walls.stl")).c("green").alpha(0.2).addShadow( z=-0.5) self.obs = vplt.load( absfilepath("data/obs.stl")).c("red").addShadow(z=-0.5) self.lexus = vplt.load(absfilepath("data/lexus_hs.obj")).scale([ 0.01, 0.01, 0.01 ]).texture(absfilepath("data/lexus_hs_diffuse.jpg")).rotateZ(180) self.plotter = vplt.Plotter(bg='white', axes={ 'xyGrid': True, 'zxGrid2': True, 'showTicks': True })
def load_volume_file(filepath, **kwargs): """ Load a volume file (e.g., .nii) and return vtk actor :param filepath: path to file :param **kwargs: """ from vtkplotter import Volume, load if not os.path.isfile(filepath): raise FileNotFoundError(filepath) if ".x3d" in filepath.lower(): raise ValueError( "brainrender cannot use .x3d data as they are not supported by vtkplotter" ) elif "nii" in filepath.lower() or ".label" in filepath.lower(): import nibabel as nb data = nb.load(filepath) d = data.get_fdata() act = Volume(d, **kwargs) else: act = load(filepath, **kwargs) if act is None: raise ValueError("Could not load {}".format(filepath)) return act
def _load_cached_neuron(self, neuron_name, params): """ Load a cached neuron's VTK actors :param neuron_name: str with neuron name """ if not neuron_name or neuron_name is None: return None # Load the yaml file with metadata about previously rendered neurons if not neuron_name in self.cache_metadata.keys( ): # the neuron was cached before the metadata was in place return None # Check if the params match those of the cached neuron cached_params = self.cache_metadata[neuron_name] diff_params = [v1 for v1,v2 in zip(cached_params.values(), params.values())\ if v1 != v2] if diff_params: return None # All is good with the params, load cached actors if self.render_neurites: if self.render_dendrites and self.render_axons: allowed_components = ['soma', 'axon', 'dendrites'] skipped_components = [] elif not self.render_dendrites and not self.render_axons: allowed_components = ['soma'] skipped_components = ['axon', 'dendrites'] elif not self.render_dendrites: allowed_components = ['soma', 'axon'] skipped_components = ['dendrites'] else: allowed_components = ['soma', 'dendrites'] skipped_components = ['axon'] else: allowed_components = ['soma'] skipped_components = ['axon', 'dendrites'] neuron_files = [ f for f in listdir(self.morphology_cache) if neuron_name in f ] if not neuron_files: return None else: neuron_actors = {} for f in neuron_files: component = os.path.split(f)[-1].split(".")[0].split("_")[-1] if component not in allowed_components and component not in skipped_components: raise ValueError( "Weird file name, unsure what to do: {}".format(f)) elif component not in allowed_components and component in skipped_components: continue neuron_actors[component] = load(f) return neuron_actors
def load_save_neuron(self, neuron_file, neuron=None): neuron_name = os.path.split(neuron_file)[-1].split('.swc')[0] savepath = os.path.join(self.morphology_cache, neuron_name + '.vtk') if neuron is None and os.path.isfile(savepath): return load(savepath) elif neuron is None: return None elif neuron is not None: neuron.write(savepath)
def __init__(self, parent=None): QtWidgets.QMainWindow.__init__(self, parent) self.setupUi(self) self.vtkWidget = QVTKRenderWindowInteractor(self) self.vtkLayout.addWidget(self.vtkWidget) self.plt = Plotter(qtWidget=self.vtkWidget, axes=1, bg='white') self.plt += load(datadir + 'shark.ply').c('cyan') self.plt.show()
def __init__(self): self.lexus = vplt.load(absfilepath("data/lexus_hs.obj")).scale([ 0.01, 0.01, 0.01 ]).texture(absfilepath("data/lexus_hs_diffuse.jpg")).rotateZ(180) self.plotter = vplt.Plotter(bg='white', axes={ 'xyGrid': True, 'zxGrid2': True, 'showTicks': True }) self.goal = vplt.Sphere(pos=(0, 0, 0.2), r=0.2, c="gold", alpha=0.3) self.obstacles = []
def download_and_write_mesh(self, acronym, obj_path): print(f"Downloading mesh data for {acronym}") path = self.structures.loc[self.structures.acronym == acronym].obj_path.values[0] url = f"{self._url_paths['data']}/{path}" # download and write .obj mesh_data = request(url).content.decode("utf-8").split("\n") with open(obj_path, 'w') as f: for md in mesh_data: f.write(f"{md}\n") f.close() # return the vtk actor return load(obj_path)
def load_mesh_from_file(filepath, *args, **kwargs): """ Load a a mesh or volume from files like .obj, .stl, ... :param filepath: path to file :param **kwargs: """ if not os.path.isfile(filepath): raise FileNotFoundError(filepath) try: actor = load(filepath, *args, **kwargs) except: actor = Volume(load_volume_file(filepath, *args, **kwargs)) return actor
def _get_structure_mesh(self, acronym, **kwargs): """ Get's the mesh for a brainregion, for this atlas it's just for getting/making the root mesh """ if acronym != 'root': raise ValueError(f'The atlas {self.atlas_name} only has one structure mesh: root. Argument {acronym} is not valid') objpath = os.path.join(self.data_folder,'objs_smoothed', 'root2.obj') if not os.path.isfile(objpath): root = self._make_root(objpath) else: root = load(objpath) root.c(ROOT_COLOR).alpha(ROOT_ALPHA) return root
def convert(path): EXPORT_PATH = os.path.join(os.getcwd(), "output", "stl") if not os.path.exists(EXPORT_PATH): os.makedirs(EXPORT_PATH) start_time = time.time() # print("Relative obtained {}".format(path)) # FILE_NAME = "test.tif" # FILE_PATH = os.path.join(INPUT_PATH, FILE_NAME) FILE_PATH = os.path.join(os.getcwd(), path) # print("Absolute obtained {}".format(FILE_PATH)) # Set Params THRESHOLD = 80 # Load Data # v = load(FILE_PATH) # Volume a = load(FILE_PATH, threshold=THRESHOLD) # isosurfacing on the fly print("Loading TIF Stack") # vp1 = show(v, a, shape=(1, 2), axes=8, viewup='z') # save(a, "output.obj", binary=True) full_filename = os.path.split(path) only_filename = full_filename[len(full_filename) - 1] macro_name = only_filename.split('.') output_name = macro_name[0] # Save Path EXPORT_NAME = output_name + ".stl" # macro_name = FILE_NAME.split('.') # EXPORT_NAME = macro_name[0] + ".stl" EXPORT_FILE = os.path.join(EXPORT_PATH, EXPORT_NAME) exp.write(a, EXPORT_FILE, binary=True) execution_time = (time.time() - start_time) print("Export to .STL completed") print("STL Generation Execution time : {0:.2f}s".format( round(execution_time, 2))) return EXPORT_NAME
''' Create a set of transparencies which can be passed to method pointColors() ''' from vtkplotter import load, show, Text mesh = load('data/beethoven.ply') # pick y coordinates of vertices and use them as scalars scals = mesh.coordinates()[:,1] # define opacities in the range of the scalar, # at min(scals) alpha is 0.1, # at max(scals) alpha is 0.9: alphas = [0.1, 0.1, 0.3, 0.4, 0.9] mesh.pointColors(scals, alpha=alphas, cmap='copper') #print(mesh.scalars('pointColors_copper')) # retrieve scalars show([mesh, Text(__doc__)], axes=9)
A tiff stack is a set of image slices in z. The scalar value (intensity of white) is used to create an isosurface by fixing a threshold. In this example the level of white is in the range 0=black -> 150=white If threshold=None this is set to 1/3 of the scalar range. - Setting connectivity to True discards the small isolated pieces of surface and only keeps the largest connected surface. - Smoothing applies a gaussian smoothing with a standard deviation which is expressed in units of pixels. - If the spacing of the tiff stack is uneven in xyz, this can be fixed by setting scaling factors with scaling=[xfac,yfac,zfac] ''' print(__doc__) from vtkplotter import show, load # Read volume data from a tif file: f = 'data/embryo.tif' a0 = load(f, threshold=80, connectivity=1) a1 = load(f, threshold=80, connectivity=0) a2 = load(f, smoothing=2) vp1 = show([a0, a1, a2], shape=(1, 3), axes=0, interactive=1) # Can also read SLC files a3 = load('data/embryo.slc', c='g', smoothing=1, connectivity=1) # newPlotter triggers the instantiation of a new Plotter object vp2 = show(a3, verbose=0, pos=(300, 300), newPlotter=True)
""" How to share the same color map across different meshes. """ from vtkplotter import load, Text2D, show, datadir ##################################### man1 = load(datadir+"man.vtk") scals = man1.points()[:, 2] * 5 + 27 # pick z coordinates [18->34] man1.pointColors(scals, cmap="jet", vmin=18, vmax=44) ##################################### man2 = load(datadir+"man.vtk") scals = man2.points()[:, 2] * 5 + 37 # pick z coordinates [28->44] man2.pointColors(scals, cmap="jet", vmin=18, vmax=44) show([[man1, Text2D(__doc__)], man2], N=2, elevation=-40)
# surface and only keeps the largest connected surface. # # - Smoothing applies a gaussian smoothing with a standard deviation # which is expressed in units of pixels. # # - Backface color is set to violet (bc='v') to spot where the vtk # reconstruction is (by mistake!) inverting the normals to the surface. # # - If the spacing of the tiff stack is uneven in xyz, this can be # corrected by setting scaling factors with scaling=[xfac,yfac,zfac] from vtkplotter import Plotter, load # Read volume data from a tif file: f = 'data/embryo.tif' vp = Plotter(shape=(1, 3), axes=0) a0 = load(f, bc='v', threshold=80, connectivity=1, legend='connectivity=True') a1 = load(f, bc='v', threshold=80, connectivity=0, legend='connectivity=False') a2 = load(f, bc='v', smoothing=2, legend='thres=automatic\nsmoothing=2') vp.show(a0, at=0) vp.show(a1, at=1) vp.show(a2, at=2) # Can also read SLC files #(NB: vp2.load instead of load. This appends the new actor in vp2.actors): vp2 = Plotter(pos=(300, 300)) vp2.load('data/embryo.slc', c='g', bc='v', smoothing=1, connectivity=1) vp2.show()
def get_drosophila_mesh_from_region(region, paths, **kwargs): """ :param region: :param paths: :param **kwargs: """ if not isinstance(region, (tuple, list)): region = [region] check = False else: check = True metadata = get_drosophila_regions_metadata(paths.metadata) if "color" in list(kwargs.keys()): color = kwargs.pop("color", DEFAULT_STRUCTURE_COLOR) elif "c" in list(kwargs.keys()): color = kwargs.pop("c", DEFAULT_STRUCTURE_COLOR) if "color" in list(kwargs.keys()): del kwargs["color"] elif "c" in list(kwargs.keys()): del kwargs["c"] meshes = [] for reg in region: if reg.lower() == "root": meshname = drosophila_root ## UNDEFINED!!?? mesh = load(meshname, c=color, **kwargs) mesh = mesh.smoothLaplacian().subdivide(2) meshes.append(mesh) else: if isinstance(reg, int): entry = metadata.loc[metadata.Id == reg] elif isinstance(reg, str): entry = metadata.loc[metadata['acronym'] == reg] else: raise ValueError("Unrecognized value for region while trying to get mesh for rat: {}".format(reg)) try: eid = entry.Id.values[0] if len(eid) == 1: meshname = os.path.join(paths.drosophila_meshes, "domains/AdultBrainDomain000{}.obj".format(eid)) if len(eid) == 2: meshname = os.path.join(paths.drosophila_meshes, "domains/AdultBrainDomain00{}.obj".format(eid)) if len(eid) == 3: meshname = os.path.join(paths.drosophila_meshes, "domains/AdultBrainDomain0{}.obj".format(eid)) if not os.path.isfile(meshname): raise FileExistsError(meshname) mesh = load(meshname, c=color, **kwargs) mesh = mesh.smoothLaplacian().subdivide(2) meshes.append(mesh) except: print("Could not load rat region: {}".format(entry["acronym"].values[0])) return None if not check: return meshes[0] else: return meshes
"""Identify and fill holes of an input mesh. Holes are identified by locating boundary edges, linking them together into loops, and then triangulating the resulting loops. """ from vtkplotter import load, show, datadir a = load(datadir+"bunny.obj").lw(0.1) # size = approximate limit to the size of the hole to be filled. b = a.clone().pos(.2,0,0).fillHoles(size=0.1) b.color("lb").legend("filled mesh") show(a, b, __doc__, elevation=-70)
""" Split a mesh by connectivity and order the pieces by increasing area. """ print(__doc__) from vtkplotter import splitByConnectivity, load, show, datadir em = load(datadir + "embryo.tif", threshold=80) # return the list of the largest 10 connected meshes: splitem = splitByConnectivity(em, maxdepth=40)[0:9] splitem[0].alpha(0.5).phong() # make the largest part transparent show([em, splitem], N=2, axes=1)
""" Set a jpeg background image on a vtkRenderingWindow layer, after the first rendering it can be zoomed to fill the window. """ from vtkplotter import Plotter, load, Polygon, Text, datadir doc = Text(__doc__, c="k", bg="w") vp = Plotter(N=2, size=(400, 800), axes=4, sharecam=0, bg=datadir + "images/tropical.jpg") a1 = load(datadir + "shapes/flamingo.3ds").rotateX(-90) a2 = Polygon() vp.show(a1, doc, at=0) vp.backgroundRenderer.GetActiveCamera().Zoom(2.5) vp.show(a2, at=1, interactive=1)
"""Insert 2D and 3D scalarbars in the rendering scene""" from vtkplotter import load, datadir, show shape = load(datadir + "lamp.vtk") ms = [] cmaps = ("jet", "PuOr", "viridis") for i in range(3): s = shape.clone().pos(0, i * 2.2, 0) # colorize mesh scals = s.points()[:, 2] s.pointColors(scals, cmap=cmaps[i]) ms.append(s) # add 2D scalar bar to first mesh ms[0].addScalarBar(title="my scalarbar\nnumber #0") #2D # add 3D scalar bars ms[1].addScalarBar3D(title="scalarbar #1", sy=3) sc = ms[2].addScalarBar3D( pos=(1, 0, -5), c="k", sy=2.8, # change y-size title="A viridis 3D\nscalarbar to play with", titleXOffset=-2, # offset of labels titleSize=1.5) sc.rotateX(90) # make it vertical
from vtkplotter import load, datadir, show vol = load(datadir + 'embryo.slc').alpha([0, 0, 1]).c('hot_r') #vol.addScalarBar(title='Volume', pos=(0.8,0.55)) vol.addScalarBar3D(title='Voxel intensity', c='k') sl = vol.slicePlane(origin=vol.center(), normal=(0, 1, 1)) sl.pointColors(cmap='viridis') \ .lighting('ambient') \ .addScalarBar(title='Slice') show( vol, sl, "Slice a Volume with an arbitrary plane", axes=1, )
"""Set a jpeg background image on a vtkRenderingWindow layer, after the first rendering it can be zoomed to fill the window.""" from vtkplotter import Plotter, load, Polygon, Text, datadir doc = Text(__doc__, c="k", bg="w") vp = Plotter(N=2, size=(400, 800), axes=4, sharecam=0, bg=datadir + "images/tropical.jpg") a1 = load(datadir + "flamingo.3ds").rotateX(-90) a2 = Polygon() vp.show(a1, doc, at=0) vp.backgroundRenderer.GetActiveCamera().Zoom(2.5) vp.show(a2, at=1, interactive=1)
''' Example on how to specify a color for each individual cell or point of an actor's mesh. Keyword depthpeeling may improve the rendering of transparent objects. ''' from vtkplotter import load, Text, show doc = Text(__doc__, pos=1, c='w') man = load('data/shapes/man.vtk') # let the scalar be the z coordinate of the mesh vertices scals = man.coordinates()[:, 2] # custom color map with optional opacity (here: 1, 0.2 and 0.8) mymap = ['darkblue', 'cyan 0.2', (1, 0, 0, 0.8)] # - or by predefined color numbers: #mymap = [i for i in range(10)] # - or by generating a palette betwwen 2 colors: #from vtkplotter.colors import makePalette #mymap = makePalette('pink', 'green', N=500, hsv=True) man.pointColors(scals, cmap=mymap).addScalarBar() show([man, doc], viewup='z', axes=8, depthpeeling=1)
import numpy as np from keras.models import Sequential from keras.layers import Dense from vtkplotter import load, Volume, isosurface, show, datadir maxradius = 0.2 neurons = 30 epochs = 20 image = load(datadir + "embryo.tif").imagedata() vmin, vmax = image.GetScalarRange() nx, ny, nz = image.GetDimensions() print("Scalar Range:", vmin, vmax, "Dimensions", image.GetDimensions()) visdata = np.zeros([nx, ny, nz]) datalist, scalars = [], [] lsx = np.linspace(0, 1, nx, endpoint=False) lsy = np.linspace(0, 1, ny, endpoint=False) lsz = np.linspace(0, 1, nz, endpoint=False) for i, x in enumerate(lsx): for j, y in enumerate(lsy): for k, z in enumerate(lsz): s = image.GetScalarComponentAsDouble(i, j, k, 0) s = (s - vmin) / (vmax - vmin) visdata[i, j, k] = s datalist.append([x, y, z]) scalars.append(s) datalist = np.array(datalist) scalars = np.array(scalars)
fig.suptitle('Array') axs[0].imshow(b) axs[1].imshow(a) axs[2].imshow(c) #plt.figure() #plt.imshow(b) #plt.imshow(a,b,c) #imgplot = plt.imshow(c) plt.show() elif "new" in var.lower(): import vtk from PyQt5 import Qt import vtkplotter as vtkp from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor vol = vtkp.load(pathout) if __name__ == "__main__": app = Qt.QApplication(sys.argv) window = MainWindow() sys.exit(app.exec_()) sys.exit() class MainWindow(Qt.QMainWindow): def __init__(self, parent=None): Qt.QMainWindow.__init__(self, parent) self.frame = Qt.QFrame() self.vl = Qt.QVBoxLayout()
# From url: https://github.com/marcomusy/vtkplotter/issues/79 import sys import vtk from PyQt5 import Qt from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor from vtkplotter import load, datadir vol = load(datadir + 'embryo.tif') class MainWindow(Qt.QMainWindow): def __init__(self, parent=None): Qt.QMainWindow.__init__(self, parent) self.frame = Qt.QFrame() self.vl = Qt.QVBoxLayout() self.vtkWidget = QVTKRenderWindowInteractor(self.frame) self.vl.addWidget(self.vtkWidget) self.ren = vtk.vtkRenderer() self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() # Create source source = vtk.vtkSphereSource() source.SetCenter(0, 0, 0) source.SetRadius(1000.0) # Create a mapper
''' Identifies and fills holes in input mesh. Holes are identified by locating boundary edges, linking them together into loops, and then triangulating the resulting loops. size: approximate limit to the size of the hole that can be filled. ''' from vtkplotter import load, show, Text a = load('data/shapes/bunny.obj') b = a.clone().fillHoles(size=0.1) b.color('b').wire(True).legend('filled mesh') doc = Text(__doc__) show([a, b, doc], elevation=-70)
""" Extracts the cells where scalar value satisfies a threshold criterion. """ from vtkplotter import load, Text, show, datadir doc = Text(__doc__) man = load(datadir+"shapes/man.vtk") scals = man.coordinates()[:, 1] + 37 # pick y coords of vertices man.pointColors(scals, cmap="cool") man.addScalarBar(title="threshold", horizontal=True) # make a copy and threshold the mesh cutman = man.clone().threshold(scals, vmin=36.9, vmax=37.5) # distribute the actors on 2 renderers show([[man, doc], cutman], N=2, elevation=-30, axes=0)
############################################################ # Please install pyshtools to run this example # Follow instructions at https://shtools.oca.eu/shtools import pyshtools from scipy.interpolate import griddata from vtkplotter import Points, load, mag, Text, show, spher2cart, datadir print(__doc__) ############################################################# lmax = 20 # maximum degree of the spherical harm. expansion N = 30 # number of grid intervals on the unit sphere rmax = 1.5 # line length x0 = [0, 0, 0] # set object at this position ############################################################# shape = load(datadir + 'pumpkin.vtk').normalize().pos(x0).lineWidth(.1) show(shape, at=0, N=2, bg='w', axes={'zxGrid': False}) ############################################################ # cast rays from the center and find intersections agrid, pts = [], [] for th in np.linspace(0, np.pi, N, endpoint=False): lats = [] for ph in np.linspace(0, 2 * np.pi, N, endpoint=False): p = spher2cart(rmax, th, ph) intersections = shape.intersectWithLine([0, 0, 0], p) # if len(intersections): value = mag(intersections[0]) lats.append(value) pts.append(intersections[0])
''' Split a mesh by connectivity and order the pieces by increasing area. ''' print(__doc__) from vtkplotter import splitByConnectivity, load, show blobs = load('data/embryo.tif') # search up to the 40th subunit of mesh, return a list # of length 40, but only keep the largest 10: sblobs = splitByConnectivity(blobs, maxdepth=40)[0:9] sblobs[0].alpha(0.05) # make the largest part transparent show([blobs, sblobs], N=2, zoom=1.2)
""" Make a icon actor to indicate orientation or for comparison and place it in one of the 4 corners within the same renderer. """ from vtkplotter import Plotter, load, Text, datadir vp = Plotter(axes=5, bg="white") # type 5 builds an annotated orientation cube a270 = load(datadir+"270.vtk", c="blue", bc="v") vp.show(interactive=0) vlg = load(datadir+"images/vtk_logo.png", alpha=0.5) vp.addIcon(vlg, pos=1) elg = load(datadir+"images/embl_logo.jpg") vp.addIcon(elg, pos=2, size=0.06) a1 = load(datadir+"250.vtk", c=2) a2 = load(datadir+"290.vtk", alpha=0.4) icon = a1 + a2 # vtkActor + vtkActor = vtkAssembly vp.addIcon(icon, pos=4) # 4=bottom-right vp.add(Text(__doc__, pos=8)) vp.show(a270, interactive=1)