def write_neuron_to_cache(self, neuron_name, neuron, _params): # Write params to file save_yaml(self.get_cache_params_filename(neuron_name), _params) # Write neurons to file file_names = self.get_cache_filenames(neuron_name) if isinstance(neuron, Mesh): write(neuron, [f for f in file_names if f.endswith("soma.obj")][0]) else: if not isinstance(neuron, dict): raise ValueError( f"Invalid neuron argument passed while caching: {neuron}") for key, actor in neuron.items(): if key == "whole_neuron": fname = [f for f in file_names if f.endswith(f"{key}.obj")] write(actor, fname[0]) else: # Get a single actor for each neuron component. # If there's no data for the component create an empty actor if not isinstance(actor, Mesh): if isinstance(actor, (list, tuple)): if len(actor) == 1: actor = actor[0] elif not actor or actor is None: actor = Mesh() else: try: actor = merge(actor) except: raise ValueError( f"{key} actor should be a mesh or a list of 1 mesh not {actor}" ) if actor is None: actor = Mesh() # Save to file fname = [f for f in file_names if f.endswith(f"{key}.obj")] if fname: write(actor, fname[0]) else: raise ValueError( f"No filename found for {key}. Filenames {file_names}" )
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) self.plt += Mesh(dataurl + 'shark.ply').c('cyan') self.plt.show(interactorStyle=0)
"""Find the overlap area of 2 triangles""" from vedo import Mesh, precision, show import numpy as np verts1 = [(1.9, 0.50), (2.1, 0.8), (2.4, 0.4)] verts2 = [(2.3, 0.75), (1.7, 0.4), (2.1, 0.3)] faces = [(0, 1, 2)] m1 = Mesh([verts1, faces]).c('g').lw(4).wireframe() m2 = Mesh([verts2, faces]).c('b').lw(4).wireframe() a1 = precision(m1.area(), 3) + " \mum\^2" a2 = precision(m2.area(), 3) + " \mum\^2" vig1 = m1.vignette('Triangle 1\nA=' + a1, point=(2.1, 0.7), s=0.012, offset=(-0.3, 0.04)) vig2 = m2.vignette('Triangle 2\nA=' + a2, point=(1.9, 0.4), s=0.012, offset=(0.2, -0.2)) m3 = m1.clone().wireframe(False).c('tomato').lw(0) zax = (0, 0, 1) v0, v1, v2 = np.insert(np.array(verts2), 2, 0, axis=1) m3.cutWithPlane(origin=v0, normal=np.cross(zax, v1 - v0)) if m3.NPoints(): m3.cutWithPlane(origin=v1, normal=np.cross(zax, v2 - v1))
"""Manually build a mesh from points and faces""" from vedo import Mesh, printc, show verts = [(50, 50, 50), (70, 40, 50), (50, 40, 80), (80, 70, 50)] faces = [(0, 1, 2), (2, 1, 3), (1, 0, 3), (0, 2, 3)] verts = [(-1.5, 0, -1.5), (-1.5, 0, 1.5), (1.5, 0, 1.5), (1.5, 0, -1.5), (-1.5, 2, -1.5), (-1.5, 2, 1.5), (1.5, 2, 1.5), (1.5, 2, -1.5)] faces = [(3, 2, 1, 0), (0, 1, 5, 4), (4, 5, 6, 7), (2, 3, 7, 6), (1, 2, 6, 5), (4, 7, 3, 0)] mesh = Mesh([verts, faces]) mesh.frontFaceCulling(True).backColor('violet').lineColor('tomato').lineWidth( 2) labs = mesh.labels('id') show(mesh, labs, __doc__, viewup='z', axes=1)
method='nearest') currIdx = 0 for i in range(n): if i not in TrIdx: latNN[i] = unknownCoord[currIdx] currIdx += 1 else: latNN[i] = mapLAT[i] updatedFaces = magicLAT.updateFaces(vertices, faces, latNN, TrCoord, EDGE_THRESHOLD) latEst = magicLAT.magicLAT(vertices, faces, TrIdx, TrCoord, TrVal, EDGE_THRESHOLD) mesh = Mesh([vertices, faces]) # mesh.backColor('white').lineColor('black').lineWidth(0.25) mesh.c('grey') size = (100, 800) fontSize = 35 verPoints = Points(vertices, r=10, c='white') origLatPoints = Points(OrigLatCoords, r=10).cmap('gist_rainbow', OrigLatVals, vmin=MINLAT, vmax=MAXLAT).addScalarBar( c='white', title='LAT (ms) ', titleFontSize=fontSize, size=size)
from tessagon.misc.shapes import general_torus, one_sheet_hyperboloid, klein, warp_var from vedo import Mesh, show # --------------------------------------------------------- options = dict( u_range=[0.0, 1.0], v_range=[0.0, 1.0], u_num=40, v_num=6, v_twist=True, function=klein, adaptor_class=VtkAdaptor, ) poly_data = RhombusTessagon(**options).create_mesh() rhombus = Mesh(poly_data).x(-5).computeNormals() rhombus.lineWidth(1).backColor('tomato') # --------------------------------------------------------- options = dict( u_range=[-1.0, 1.0], v_range=[0.0, 1.0], u_num=4, v_num=10, u_cyclic=False, v_cyclic=True, function=one_sheet_hyperboloid, adaptor_class=VtkAdaptor, ) poly_data = DodecaTessagon(**options).create_mesh() dodeca = Mesh(poly_data).x(5).computeNormals()
if not os.path.isdir(OUTDIR): os.makedirs(OUTDIR) if not os.path.isdir(outSubDir): os.makedirs(outSubDir) """ Read the files """ print('\nProcessing ' + nm + ' ...\n') [vertices, faces] = readMesh(os.path.join(DATADIR, meshFile)) [OrigLatCoords, OrigLatVals] = readLAT(os.path.join(DATADIR, latFile)) if ablFile != '': ablFile = os.path.join(DATADIR, ablFile) else: ablFile = None print('No ablation file available for this mesh... continuing...\n') """ Pre-process the mesh and LAT samples. """ mesh = Mesh([vertices, faces]) mesh.c('grey') n = len(vertices) mapIdx = [i for i in range(n)] mapCoord = [vertices[i] for i in mapIdx] # Map the LAT samples to nearest mesh vertices allLatIdx, allLatCoord, allLatVal = utils.mapSamps(mapIdx, mapCoord, OrigLatCoords, OrigLatVals) M = len(allLatIdx) # Identify and exclude anomalous LAT samples anomalous = np.zeros(M)
"""Mouse click and other type of events will trigger a call to a custom function""" from vedo import printc, Plotter, Mesh, datadir printc("Click object to trigger a function call", invert=1) # callback functions def onLeftClick(event): if not event.actor: return printc("Left button pressed on", [event.actor], c=event.actor.color()) # printc('full dump of event:', event) def onEvent(event): printc(event.name, 'happened at mouse position', event.picked2d) ###################### tea = Mesh(datadir + "teapot.vtk").c("gold") mug = Mesh(datadir + "mug.ply").rotateX(90).scale(8).pos(2, 0, -.7).c("silver") plt = Plotter(axes=11) plt.addCallback('LeftButtonPress', onLeftClick) plt.addCallback('Interaction', onEvent) # mouse dragging triggers this plt.show(tea, mug, __doc__)
if not os.path.isdir(OUTDIR): os.makedirs(OUTDIR) if not os.path.isdir(outSubDir): os.makedirs(outSubDir) """ Read the files """ print('\nProcessing ' + nm + ' ...\n') [vertices, faces] = readMesh(os.path.join(DATADIR, meshFile)) [OrigLatCoords, OrigLatVals] = readLAT(os.path.join(DATADIR, latFile)) if ablFile != '': ablFile = os.path.join(DATADIR, ablFile) else: ablFile = None print('No ablation file available for this mesh... continuing...\n') """ Pre-process the mesh and LAT samples. """ mesh = Mesh([vertices, faces]) mesh.c('grey') n = len(vertices) mapIdx = [i for i in range(n)] mapCoord = [vertices[i] for i in mapIdx] # Map the LAT samples to nearest mesh vertices allLatIdx, allLatCoord, allLatVal = utils.mapSamps(mapIdx, mapCoord, OrigLatCoords, OrigLatVals) M = len(allLatIdx) # Identify and exclude anomalous LAT samples if remove_anomalies:
"""Share the same color map across different meshes""" from vedo import Mesh, show, dataurl ##################################### man1 = Mesh(dataurl + "man.vtk") scals = man1.points()[:, 2] * 5 + 27 # pick z coordinates [18->34] man1.cmap("rainbow", scals, vmin=18, vmax=44) ##################################### man2 = Mesh(dataurl + "man.vtk") scals = man2.points()[:, 2] * 5 + 37 # pick z coordinates [28->44] man2.cmap("rainbow", scals, vmin=18, vmax=44).addScalarBar() show([(man1, __doc__), man2], N=2, elevation=-40, axes=11)
"""Add a square button with N possible internal states to a rendering window that calls an external function""" from vedo import Plotter, Mesh, dataurl, printc plt = Plotter(axes=11) mesh = Mesh(dataurl + "magnolia.vtk").c("v").flat() # add a button to the current renderer (e.i. nr1) def buttonfunc(): mesh.alpha(1 - mesh.alpha()) # toggle mesh transparency bu.switch() # change to next status printc(bu.status(), box="_", dim=True) bu = plt.addButton( buttonfunc, pos=(0.7, 0.05), # x,y fraction from bottom left corner states=["click to hide", "click to show"], c=["w", "w"], bc=["dg", "dv"], # colors of states font="courier", # arial, courier, times size=25, bold=True, italic=False, ) plt.show(mesh, __doc__).close()
"""Manually build a mesh from points and faces""" from vedo import Mesh, printc, show verts = [(50,50,50), (70,40,50), (50,40,80), (80,70,50)] faces = [(0,1,2), (2,1,3), (1,0,3)] # (the first triangle face is formed by vertex 0, 1 and 2) # Build the polygonal Mesh object: mesh = Mesh([verts, faces]) mesh.backColor('violet').lineColor('tomato').lineWidth(2) labs = mesh.labels('id').c('black') # 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).close()
"""Moebius strip with matplotlib.tri.Triangulation """ # https://matplotlib.org/mpl_examples/mplot3d/trisurf3d_demo2.py import numpy as np from matplotlib.tri import Triangulation from vedo import Mesh, show # Make a mesh in the space of parameterisation variables u and v u = np.linspace(0, 2.0 * np.pi, endpoint=True, num=50) v = np.linspace(-0.5, 0.5, endpoint=True, num=10) u, v = np.meshgrid(u, v) u, v = u.flatten(), v.flatten() # Mobius mapping, taking a u, v pair and returning x, y, z x = (1 + 0.5 * v * np.cos(u/2.0)) * np.cos(u) y = (1 + 0.5 * v * np.cos(u/2.0)) * np.sin(u) z = 0.5 * v * np.sin(u/2.0) # Triangulate parameter space to determine the triangle faces tri = Triangulation(u, v) points, faces = np.c_[x,y,z], tri.triangles mesh = Mesh((points, faces), c='orange') mesh.computeNormals().phong().lineWidth(0.1).lighting('glossy') show(mesh, __doc__, axes=1)
"""Find the overlap area of 2 triangles""" from vedo import Mesh, show import numpy as np verts1 = [(1.9, 0.5), (2.1, 0.8), (2.4, 0.4)] verts2 = [(2.3, 0.8), (1.8, 0.4), (2.1, 0.3)] faces = [(0, 1, 2)] m1 = Mesh([verts1, faces]).c('g').lw(4).wireframe() m2 = Mesh([verts2, faces]).c('b').lw(4).wireframe() m3 = m1.clone().wireframe(False).c('tomato').lw(0) zax = (0, 0, 1) v0, v1, v2 = np.insert(np.array(verts2), 2, 0, axis=1) m3.cutWithPlane(origin=v0, normal=np.cross(zax, v1 - v0)) if m3.NPoints(): m3.cutWithPlane(origin=v1, normal=np.cross(zax, v2 - v1)) if m3.NPoints(): m3.cutWithPlane(origin=v2, normal=np.cross(zax, v0 - v2)) print("Area of overlap:", m3.area()) show(m1, m2, m3, __doc__, axes=8)
""" print(__doc__) from vedo import Plotter, Mesh, dataurl # these are the some matplotlib color maps maps = [ "afmhot", "binary", "bone", "cool", "coolwarm", "copper", "gist_earth", "gray", "hot", "jet", "rainbow", "winter", ] mug = Mesh(dataurl + "mug.ply") scalars = mug.points()[:, 1] # let y-coord be the scalar plt = Plotter(N=len(maps)) for i, key in enumerate(maps): # for each available color map name imug = mug.clone(deep=False).cmap(key, scalars, n=5) plt.show(imug, key, at=i) plt.show().interactive().close()
"""Manually build a mesh from points and faces""" from vedo import Mesh, printc, show verts = [(50, 50, 50), (70, 40, 50), (50, 40, 80), (80, 70, 50)] faces = [(0, 1, 2), (2, 1, 3), (1, 0, 3)] # (the first triangle face is formed by vertex 0, 1 and 2) # Build the polygonal Mesh object: m = Mesh([verts, faces]) m.backColor('violet').lineColor('tomato').lineWidth(2) # retrieve them as numpy arrays printc('points():\n', m.points(), c=3) printc('faces(): \n', m.faces(), c=3) show(m, __doc__, viewup='z', axes=8)
"""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 vedo import Mesh, show, dataurl a = Mesh(dataurl+"bunny.obj").lw(0.1).bc('red') # 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").bc('green').legend("filled mesh") show(a, b, __doc__, elevation=-70).close()
"""Insert 2D and 3D scalarbars in the rendering scene""" from vedo import Mesh, dataurl, show shape = Mesh(dataurl + "lamp.vtk") ms = [] cmaps = ("jet", "PuOr", "viridis") for i in range(3): s = shape.clone(deep=False).pos(0, i * 2.2, 0) # colorize mesh scals = s.points()[:, 2] s.cmap(cmaps[i], scals) 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(c="k", 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", titleFont='Quikhand', titleXOffset=-2, # offset of labels titleSize=1.5) sc.scalarbar.rotateX(90) # make it vertical
"""Read and show meshio objects""" import meshio from vedo import download, show, Mesh fpath = download('https://vedo.embl.es/examples/data/shuttle.obj') mesh = meshio.read(fpath) # vedo understands meshio format for polygonal data: # show(mesh, __doc__, axes=7) # explicitly convert it to a vedo.Mesh object: m = Mesh(mesh).lineWidth(1).color('tomato').printInfo() show(m, __doc__, axes=7).close()
"""Thin Plate Spline transformations describe a nonlinear warp transform defined by a set of source and target landmarks. Any point on the mesh close to a source landmark will be moved to a place close to the corresponding target landmark. The points in between are interpolated using Bookstein's algorithm""" from vedo import Mesh, Points, show, dataurl import numpy as np np.random.seed(1) mesh = Mesh(dataurl + "shuttle.obj").c('silver') # pick 4 random points indxs = np.random.randint(0, mesh.N(), 4) pts = mesh.points()[indxs] # and move them randomly by a little ptsource, pttarget = [], [] for ptold in pts: ptnew = ptold + np.random.rand(3) * 0.2 ptsource.append(ptold) pttarget.append(ptnew) # print(ptold,'->',ptnew) warped = mesh.clone().thinPlateSpline(ptsource, pttarget).color("b", 0.4) apts = Points(ptsource, r=15, c="r") show(mesh, warped, apts, __doc__, viewup="z", axes=1)
"""Create a set of transparencies which can be passed to method cmap()""" from vedo import Mesh, show, dataurl mesh = Mesh(dataurl + "beethoven.ply") # pick y coordinates of vertices and use them as scalars scals = mesh.points()[:, 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.cmap("copper", scals, alpha=alphas) # print(mesh.getPointArray('PointScalars')) # retrieve scalars show(mesh, __doc__, axes=9).close()
"""Build a volume from a mesh where the foreground voxels are set to 255 and the background voxels are 0""" from vedo import Mesh, dataurl, show surf = Mesh(dataurl+"bunny.obj").normalize().wireframe() vol = surf.binarize(spacing=(0.02,0.02,0.02)) vol.alpha([0,0.6]).c('blue') iso = vol.isosurface().color("blue5") show(vol, surf, __doc__, at=0, N=2, axes=9) show("..the volume is isosurfaced:", iso, at=1).interactive().close()
"""Setting illumination properties: ambient, diffuse, specular, specularPower, specularColor. """ from vedo import Plotter, Mesh, dataurl plt = Plotter(axes=1) ambient, diffuse, specular = 0.1, 0., 0. specularPower, specularColor = 20, 'white' apple = Mesh(dataurl + 'apple.ply').normalize().c('gold') for i in range(8): s = apple.clone().pos((i % 4) * 2.2, int(i < 4) * 3, 0) #s.phong() s.flat() # modify the default with specific values s.lighting('default', ambient, diffuse, specular, specularPower, specularColor) #ambient += 0.125 diffuse += 0.125 specular += 0.125 plt += s plt += __doc__ plt.show().close()
"""Mouse click and other type of events will trigger a call to a custom function""" from vedo import printc, Plotter, Mesh, dataurl printc("Click object to trigger a function call", invert=1) # callback functions def onLeftClick(event): if not event.actor: return printc("Left button pressed on", [event.actor], c=event.actor.color()) # printc('full dump of event:', event) def onEvent(event): printc(event.name, 'happened at mouse position', event.picked2d) ###################### tea = Mesh(dataurl+"teapot.vtk").c("gold") mug = Mesh(dataurl+"mug.ply").rotateX(90).scale(8).pos(2,0,-.7).c("red3") plt = Plotter(axes=11) plt.addCallback('LeftButtonPress', onLeftClick) plt.addCallback('Interaction', onEvent) # mouse dragging triggers this plt.show(tea, mug, __doc__)
"""Make a static 2D copy of a mesh and place it in the rendering window""" from vedo import Mesh, dataurl, show s = Mesh(dataurl + 'man.vtk').rotateZ(20).rotateX(-70).scale(0.2).c( 'darkgreen', 0.3) # Make a 2D snapshot of a 3D mesh # The coordinate system options are # 0. Displays # 1. Normalized Display # 2. Viewport (origin is the bottom-left corner of the window) # 3. Normalized Viewport # 4. View (origin is the center of the window) # 5. World (anchor the 2d image to mesh) # (returns a vtkActor2D) s2d = s.clone2D(pos=[0.4, 0.4], coordsys=4, c='r', alpha=1) show(s, s2d, __doc__, axes=1).close()
""" from vedo import Mesh, datadir, show # define a polygon of 4 vertices: polygon = [ [ (82, 92, 47), (87, 88, 47), # x,y,z of vertices (93, 95, 47), (88, 99, 47) ], [[0, 1, 2, 3]], # vertex connectivity ] # texture coordinates, one (u,v) pair for each vertex: tc = [(0, 0), (1, 0), (1, 1), (0, 1)] #tc = [(0,0), (2,0), (2,2), (0,2)] # create the Mesh(vtkActor) object m = Mesh(polygon) m.texture( datadir + "images/dog.jpg", tcoords=tc, interpolate=True, repeat=True, # when tcoords extend beyond [0,1] edgeClamp=False, # only used when repeat is False ) show(m, __doc__, axes=8)