def video_timestep(vplotter, video, vpoints, vtext, vobjects, tfrom, tto, nframes, tinf, cmap, cam): print("Run...") for t in np.linspace(tfrom, tto, nframes): pszs = np.mean(tinf < t, axis=0) for vpoint, psz in zip(vpoints, pszs): vpoint.color(vp.colorMap(psz, cmap, 0, 1)) # vtext.SetText(1, f"t = {t:4.1f} s") # vtext.SetNonlinearFontScaleFactor(2.0/2.7) # Recreate vtext # print(vtext.s) # vplotter.remove(vtext) # vtext = vp.Text2D(f"t = {t:4.1f} s", pos=(0.1, 0.1), s=3, c='black') # vtext = vp.Text2D(f"t = {t:4.1f} s", pos=(0.1, 0.1), s=3, c='black') # vplotter.show(vpoints, vtext, *vobjects, camera={'pos':cam['pos'], 'focalPoint':cam['focalPoint'], 'viewup':cam['viewup']}) # vplotter.clear() # vplotter.show(vpoints, vtext, *vobjects, camera={'pos':cam['pos'], 'focalPoint':cam['focalPoint'], 'viewup':cam['viewup']}) vtext = vp.Text2D(f"t = {t:4.1f} s", (10, 10), s=6, c='black') vplotter += vtext vplotter.show( camera={ 'pos': cam['pos'], 'focalPoint': cam['focalPoint'], 'viewup': cam['viewup'] }) video.addFrame() vplotter -= vtext
def keyfunc(key): global data_idx if key == 'Left' and data_idx > 0: data_idx -= 1 elif key == 'Right' and data_idx < data_length - 1: data_idx += 1 pos, path = getpos(data_idx) plt.clear() plt.add(vedo.Points(pos, c='b')) plt.add(vedo.Text2D(path, pos=(.02, .02), c='k')) plt.add(boundary_mesh) plt.render()
def __init__(self, model, project_parameters): super().__init__(model, project_parameters) ######### GUI attributes self.Continue = True self.timestep = 0 self.slider1 = Slider(0) self.Plot = vedo.Plotter(title="Simulation Results", interactive=False) self.Plot.addSlider2D(self.slider1.GenericSlider, -200, 400, value=0, pos=3, title="Pressure (MPa)") self.Plot += vedo.Text2D( 'Move the slider to change the Pressure on the Face of the Bunny', s=1.2) self.PauseButton = self.Plot.addButton( self.PauseButtonFunc, pos=(0.9, .9), # x,y fraction from bottom left corner states=["PAUSE", "CONTINUE"], c=["w", "w"], bc=["b", "g"], # colors of states font="courier", # arial, courier, times size=25, bold=True, italic=False, ) self.StopButton = self.Plot.addButton( self.StopButtonFunc, pos=(0.1, .9), # x,y fraction from bottom left corner states=["STOP"], c=["w"], bc=["r"], # colors of states font="courier", # arial, courier, times size=25, bold=True, italic=False, ) self.Plot.show()
def animate(vplotter, video, nframes, vpoints, tinf, prange=(0., 1.), time=0.0, pos=(1, 0, 0), foc=(0, 0, 0), viewup=(0, 1, 0), startpoint=True, endpoint=True): cmap = 'bwr' if startpoint and endpoint: params = np.linspace(prange[0], prange[1], nframes) elif startpoint and not endpoint: params = np.linspace(prange[0], prange[1], nframes + 1)[:-1] elif not startpoint and endpoint: params = np.linspace(prange[0], prange[1], nframes + 1)[1:] else: params = np.linspace(prange[0], prange[1], nframes + 2)[1:-1] for param in params: p = pos if not callable(pos) else pos(param) f = foc if not callable(foc) else foc(param) v = viewup if not callable(viewup) else viewup(param) t = time if not callable(time) else time(param) pszs = np.mean(tinf < t, axis=0) for vpoint, psz in zip(vpoints, pszs): vpoint.color(vp.colorMap(psz, cmap, 0, 1)) vtext = vp.Text2D(f"t = {t:4.1f} s", (10, 10), s=6, c='black') vplotter += vtext vplotter.show(camera=dict(pos=p, focalpoint=f, viewup=v)) video.addFrame() vplotter -= vtext
def viz_observation_manifold(t3, tlim, size): tmin = 0 tmax = 2 * tlim # tlim line vline1 = vp.Tube([[tmin, tlim, t3], [tmax, tlim, t3]], r=2.0) vline1.color('g') # t = 0 line vline2 = vp.Tube([[tmin, tlim, t3], [tmin, tmax, t3]], r=2.0) vline2.color((1, 1, 1)) # Manifold verts = [[tmin, tlim, t3], [tmax, tlim, t3], [tmin, tmax, t3], [tmax, tmax, t3]] triangs = [[0, 1, 3], [0, 3, 2]] vmesh1 = vp.Mesh([verts, triangs]) vmesh1.color((1, 1, 1)) # Inverse manifold verts = [[tmin, tmin, t3], [tmax, tmin, t3], [tmin, tlim, t3], [tmax, tlim, t3]] triangs = [[0, 1, 3], [0, 3, 2]] vmesh2 = vp.Mesh([verts, triangs]) vmesh2.color((0.9, 0.9, 0.9)).alpha(0.0) # Invisible points to set the extent vpoints = vp.Points([(tmin - 0.1, tmin - 0.1, tmin - 0.1), (1.01 * tmax, 1.01 * tmax, 1.01 * tmax)]).alpha(0.0) lpos = [(p, str(p)) for p in [0, 50, 100, 150]] vplotter = vp.Plotter(offscreen=True, size=size, axes=dict(xyGrid=True, yzGrid=True, zxGrid=True, xTitleSize=0, yTitleSize=0, zTitleSize=0, xPositionsAndLabels=lpos, yPositionsAndLabels=lpos, zPositionsAndLabels=lpos[1:], axesLineWidth=5, tipSize=0.02, gridLineWidth=2, xLabelSize=0.05, yLabelSize=0.05, zLabelSize=0.05, xLabelOffset=0.05, yLabelOffset=0.05, zLabelOffset=0.0, zTitleRotation=225)) vlabels = [ vp.Text2D("H", (0.09 * size[0], 0.10 * size[1]), s=3, font='Arial'), vp.Text2D("N", (0.87 * size[0], 0.16 * size[1]), s=3, font='Arial'), vp.Text2D("S", (0.49 * size[0], 0.90 * size[1]), s=3, font='Arial') ] vp.show([vline1, vline2, vmesh1, vpoints] + vlabels, camera=dict(pos=(378, 324, 450), focalPoint=(tlim, tlim, tlim + 27), viewup=(0, 0, 1))) img = vp.screenshot(None, scale=1, returnNumpy=True) vp.clear() vp.closePlotter() return img
def viz_param_manifold(filename, size): data = np.load(filename) vline = vp.Tube(data['boundary_hns'], r=0.08) vline.color('g') # HNS manifold vmesh_hns = vp.Mesh([data['verts_hns'], data['triangs_hns']]) k = 3 prior = (2 * np.pi)**(-k / 2) * (np.exp( -0.5 * np.sum(vmesh_hns.points()**2, axis=1))) vmesh_hns.pointColors(prior, cmap='Reds', vmin=0) vmesh_hns.addScalarBar(horizontal=True, nlabels=6, c='k', pos=(0.74, 0.01), titleFontSize=44) vmesh_hns.scalarbar.SetLabelFormat("%.2g") vmesh_hns.scalarbar.SetBarRatio(1.0) # Inverted HNS manifold vmesh_hnsi = vp.Mesh([data['verts_hnsi'], data['triangs_hnsi']]) # vmesh_hnsi.color([0.68, 0.68, 0.68]) vmesh_hnsi.color([0.9, 0.9, 0.9]).alpha(0.0) # Invisible points to set the extent vpoints = vp.Points([(-5.01, -5.01, -5.01), (5.01, 5.01, 5.01)]).alpha(0.0) vplotter = vp.Plotter(offscreen=True, size=size, axes=dict(xyGrid=True, yzGrid=True, zxGrid=True, xTitleSize=0, yTitleSize=0, zTitleSize=0, xHighlightZero=True, yHighlightZero=True, zHighlightZero=True, xHighlightZeroColor='b', yHighlightZeroColor='b', zHighlightZeroColor='b', numberOfDivisions=10, axesLineWidth=5, tipSize=0.02, gridLineWidth=2, xLabelSize=0.05, yLabelSize=0.05, zLabelSize=0.05, xLabelOffset=0.05, yLabelOffset=0.05, zLabelOffset=0.0, zTitleRotation=225)) vlabels = [ vp.Text2D("H", (0.09 * size[0], 0.10 * size[1]), s=3, font='Arial'), vp.Text2D("N", (0.87 * size[0], 0.16 * size[1]), s=3, font='Arial'), vp.Text2D("S", (0.49 * size[0], 0.90 * size[1]), s=3, font='Arial') ] k = 2 vecs = np.array([[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], [[k, -k, 0, 0, 0, 0], [0, 0, k, -k, 0, 0], [0, 0, 0, 0, k, -k]]]) varrows = vp.Arrows(vecs[0].T, vecs[1].T, s=1.2, c='k') vp.show([vline, vmesh_hns, vmesh_hnsi, vpoints, varrows] + vlabels, camera=dict(pos=(16, 13, 20), focalPoint=(0, 0, 1.5), viewup=(0, 0, 1))) img = vp.screenshot(None, scale=1, returnNumpy=True) vp.clear() vp.closePlotter() return img
allb = AllBoundaries() allb.mark(mfunc, 1) F = np.array([2, (i - N / 2) / N]) # some variable force displacement = solve_problem(mesh, mfunc, F) new_mesh = update(mesh, displacement) if do_remesh: mesh = remesh(new_mesh) else: mesh = new_mesh meshes.append(mesh) displacements.append(displacement) # plot things: txt = vedo.Text2D(f"step{i}") arrow = vedo.Arrow2D([0, 0], F * 20).z(1) vedo.dolfin.plot(mesh, arrow, txt, c='grey5', at=i, N=N, zoom=1.1) #PRESS q dmesh_i = meshes[0] # initial mesh dmesh_f = meshes[-1] # final mesh vmesh_i = vedo.Mesh([dmesh_i.coordinates(), dmesh_i.cells()], c='grey5').z(-1) vmesh_f = vedo.Mesh( [dmesh_f.coordinates(), dmesh_f.cells()], c='grey3').wireframe() plt = vedo.Plotter() # move a few points along the deformation of the circle seeds = vedo.Circle(r=50,
def confirm_perch_placement(environment, placed_cameras, focus_id): global approved global user_responded plt1.keyPressFunction = perch_keyfunc plt1.clear() approved = False plt2.clear() dense_env = vedo.load( '/home/simon/catkin_ws/src/mesh_partition/datasets/' + environment.name + '_1m.ply') pv_dense_env = pv.read( '/home/simon/catkin_ws/src/mesh_partition/datasets/' + environment.name + '_1m.ply') plt2.add(dense_env) plt2.show() plt3 = pv.Plotter(notebook=False) plt3.add_mesh(pv_dense_env) # plt3.show(interactive=False) # draw wireframe lineset of camera frustum env_mesh = trimesh.load( '/home/simon/catkin_ws/src/mesh_partition/datasets/' + environment.name + '_1m.ply') # env_mesh = trimesh.load(environment.full_env_path) R = np.zeros([4, 4]) R[:3, :3] = environment.R env_mesh.vertices = trimesh.transform_points(env_mesh.vertices, R) env_mesh_vedo = vedo.mesh.Mesh(env_mesh) target_mesh_pymesh = environment.generate_target_mesh(shape='box') target_mesh = trimesh.Trimesh(target_mesh_pymesh.vertices, target_mesh_pymesh.faces) target_mesh_vedo = vedo.mesh.Mesh(target_mesh) target_colors = 0.5 * np.ones([len(target_mesh.faces), 4]) target_colors[:, 0] *= 0.0 target_colors[:, 2] *= 0.0 target_mesh_vedo.alpha(0.6) target_mesh_vedo.cellIndividualColors(target_colors, alphaPerCell=True) plt2.add(target_mesh_vedo) env_mesh.visual.face_colors[:, -1] = 255.0 env_mesh_vedo.cellIndividualColors(env_mesh.visual.face_colors / 255.0, alphaPerCell=True) geom_list = [env_mesh_vedo, target_mesh_vedo] for s in environment.perch_regions: surf_mesh = trimesh.Trimesh(vertices=s.points, faces=s.faces) vedo_surf_mesh = vedo.mesh.Mesh(surf_mesh) vedo_surf_mesh.color('g') vedo_surf_mesh.opacity(0.5) geom_list.append(vedo_surf_mesh) for i in range(len(placed_cameras)): quad_mesh = trimesh.load( "/home/simon/catkin_ws/src/perch_placement/src/ui/models/white-red-black_quad2.ply" ) # offset mesh coords to match camera pose # eul = placed_cameras[i].pose[3:] # USE WALL NORMAL, NOT CAMERA POSE # R = rot3d_from_rtp(np.array([eul[2], -eul[0], -eul[1]])) R = rot3d_from_x_vec(placed_cameras[i].wall_normal) R2 = rot3d_from_rtp(np.array([0, -90, 0])) R_aug = np.zeros([4, 4]) R_aug[:3, :3] = R.dot(R2) R_aug[:3, -1] = placed_cameras[i].pose[:3] quad_mesh.vertices = trimesh.transform_points(quad_mesh.vertices, R_aug) quad_mesh_vedo = vedo.mesh.Mesh(quad_mesh) quad_mesh_vedo.cellIndividualColors(quad_mesh.visual.face_colors / 255, alphaPerCell=True) quad_mesh_pv = pv.read( "/home/simon/catkin_ws/src/perch_placement/src/ui/models/white-red-black_quad2.ply" ) pymesh_frustum = placed_cameras[i].generate_discrete_camera_mesh( degrees_per_step=10, environment=environment) pymesh_verts = pymesh_frustum.vertices.copy() pymesh_verts.flags.writeable = True pymesh_faces = pymesh_frustum.faces.copy() pymesh_faces.flags.writeable = True if i == focus_id: frustum = trimesh.Trimesh(vertices=pymesh_frustum.vertices.copy(), faces=pymesh_frustum.faces.copy()) vedo_frustum = vedo.mesh.Mesh(frustum) vedo_frustum.alpha(0.3) vedo_frustum.color("c") # geom_list.append(frustum_lines) geom_list.append(quad_mesh_vedo) geom_list.append(vedo_frustum) print("cam pose: " + str(placed_cameras[i].pose)) pose = placed_cameras[i].pose plt2.camera.SetPosition(pose[0], pose[1], pose[2]) R = rot3d_from_rtp(np.array([pose[-1], -pose[-3], -pose[-2]])) print("R: " + str(R)) focus = pose[:3] + R[:, 0] print("focus: " + str(focus)) plt2.camera.SetFocalPoint(focus[0], focus[1], focus[2]) plt2.camera.SetViewUp(R[:, 2]) plt2.camera.SetDistance(5) plt2.camera.SetClippingRange([0.2, 10]) plt2.camera.SetViewAngle(placed_cameras[i].fov[-1] * 1.1) plt2.show(resetcam=False) plt3.set_position(pose[:3]) plt3.set_viewup(R[:, 2]) plt3.set_focus(focus) plt3.show(auto_close=False, interactive=False) else: # vedo_frustum.alpha(0.1) # vedo_frustum.color("p") quad_mesh_vedo.color('o') # geom_list.append(frustum_lines) geom_list.append(quad_mesh_vedo) # geom_list.append(vedo_frustum) plt2.add(quad_mesh_vedo) plt3.add_mesh(quad_mesh_pv) # testing: test = (-plt3.get_image_depth(fill_value=0) / placed_cameras[0].range[1]) test[test > 1] = 1.0 test[test < 0] = 0.0 test = np.round(test * np.iinfo(np.uint16).max) test = test.astype(np.uint16) # test_cv = cv.normalize(-test / placed_cameras[0].range[1] * 255, 0, 255, cv.NORM_MINMAX) cv.imshow('test', test) cv.waitKey() for actor in geom_list: plt1.add(actor) plt1.add( vedo.Text2D( "Press 'y' to approve placement. Press 'n' to reject. " "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling " "\nPress 'q' when done", pos='bottom-right', c='dg', bg='g', font='Godsway')) plt1.camera.SetPosition(7.8 * np.cos(-145 * np.pi / 180.0), 7.8 * np.sin(-145 * np.pi / 180.0), 3.) plt1.camera.SetFocalPoint(-0.026929191045848594, 0.5783514020506139, 0.8268966663940324) plt1.camera.SetViewUp(np.array([0, 0, 1])) plt1.camera.SetDistance(7.8) plt1.camera.SetClippingRange([0.25, 10]) plt1.show(resetcam=False) return approved
def perch_keyfunc(key): global approved global user_responded actors = plt1.actors actors.pop(-1) plt1.clear() plt1.add(actors) if key == 'y': approved = True plt1.add( vedo.Text2D("Approve placement? pless 'q' to confirm.", pos='bottom-right', c='dg', bg='g', font='Godsway')) elif key == 'n': approved = False plt1.add( vedo.Text2D("Reject placement? Press 'q' to confirm.", pos='bottom-right', c='dg', bg='g', font='Godsway')) elif key == 'b': actors[0].backFaceCulling(True) actors[0].frontFaceCulling(False) plt1.add( vedo.Text2D( "Press 'y' to approve placement. Press 'n' to reject. " "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling " "\nPress 'q' when done", pos='bottom-right', c='dg', bg='g', font='Godsway')) elif key == 'f': actors[0].backFaceCulling(False) actors[0].frontFaceCulling(True) plt1.add( vedo.Text2D( "Press 'y' to approve placement. Press 'n' to reject. " "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling " "\nPress 'q' when done", pos='bottom-right', c='dg', bg='g', font='Godsway')) elif key == 'c': actors[0].backFaceCulling(False) actors[0].frontFaceCulling(False) plt1.add( vedo.Text2D( "Press 'y' to approve placement. Press 'n' to reject. " "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling " "\nPress 'q' when done", pos='bottom-right', c='dg', bg='g', font='Godsway')) else: plt1.add( vedo.Text2D( "Press 'y' to approve placement. Press 'n' to reject. " "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling " "\nPress 'q' when done", pos='bottom-right', c='dg', bg='g', font='Godsway')) plt1.show()
plt.add(objs, resetcam=False) return [x, y] # Load some 2D shape and make it symmetric shape = vedo.load(vedo.dataurl + 'timecourse1d.npy')[55] shaper = vedo.Line(shape).mirror('x').reverse() shape = vedo.merge(shape, shaper) x, y, _ = shape.points().T # Compute Fourier Discrete Transform in x and y separately: fourierX = DFT(x) fourierY = DFT(y) vedo.settings.defaultFont = 'Glasgo' plt = vedo.Plotter(size=(1500, 750), bg='black', axes=1, interactive=False) txt = vedo.Text2D(f"{__doc__} (order={order})", c='red9', bg='white', pos='bottom-center') plt.show(shape, txt, mode='image', zoom=1.9) objs, points = [], [] times = np.linspace(0, 2 * np.pi, len(fourierX), endpoint=False) for time in times: x, _ = epicycles(time, 0, fourierX, order) _, y = epicycles(time, np.pi / 2, fourierY, order) points.append([x, y]) plt.interactive()
def make_video(sid, rid, video_file): regpos, w, obsmask, surfaces, contacts = read_structural_data(sid, rid) vlines, vmeshes, vcontacts = viz_structure(regpos, w, surfaces, contacts) # Load results res = io.parse_csv([ f"run/solo/INC/vep/id{sid:03d}/output/r{rid:02d}_all/chain_{chain}.csv" for chain in [1, 2] ]) tinf = res['t'] t = 0.0 psz = np.mean(tinf < t, axis=0) nreg = regpos.shape[0] # Regions cmap = 'bwr' vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(regpos[i], r=4, c=vp.colorMap(psz[i], cmap, 0, 1))) else: vpoints.append( vp.Cube(regpos[i], side=6, c=vp.colorMap(psz[i], cmap, 0, 1))) vbar = vp.Points(regpos, r=0.01).pointColors(psz, cmap=cmap, vmin=0, vmax=1) vbar.addScalarBar(horizontal=True, pos=(0.8, 0.02)) vtext = vp.Text2D(f"t = {t:4.1f} s", pos=0, s=2, c='black') center = np.mean(regpos, axis=0) dist = 2.5 * (np.max(regpos[:, 1]) - np.min(regpos[:, 1])) # Video ------------------------------------------------------- vplotter = vp.Plotter(axes=0, interactive=0, offscreen=True, size=(1800, 1800)) nframes = 3000 vplotter += vpoints vplotter += vlines vplotter += vmeshes video = vp.Video(name=video_file, duration=90) ratios = np.array([30, 3, 5, 30, 5, 3, 30, 10]) frames = (nframes * ratios / np.sum(ratios)).astype(int) # Run and pause animate(vplotter, video, frames[0], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), prange=(0, 45), time=lambda p: p) animate(vplotter, video, frames[1], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=45.) ## Fly around pos = lambda angle: center + dist * np.array( [0, -np.sin(angle), np.cos(angle)]) animate(vplotter, video, frames[2], vpoints, tinf, pos=pos, foc=center, viewup=(0, 1, 1), prange=(0, np.pi / 2), time=45., endpoint=False) pos = lambda angle: center + dist * np.array( [-np.sin(angle), -np.cos(angle), 0]) animate(vplotter, video, frames[3], vpoints, tinf, pos=pos, foc=center, viewup=(0, 0, 1), prange=(0, 2 * np.pi), time=45.) pos = lambda angle: center + dist * np.array( [0, -np.sin(angle), np.cos(angle)]) animate(vplotter, video, frames[4], vpoints, tinf, pos=pos, foc=center, viewup=(0, 1, 1), prange=(np.pi / 2, 0), time=45., startpoint=False) # Pause + run + pause animate(vplotter, video, frames[5], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=45.) animate(vplotter, video, frames[6], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), prange=(45, 90), time=lambda p: p) animate(vplotter, video, frames[7], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=90.) video.close()
plt.add(vedo.Points(pos, c='b')) plt.add(vedo.Text2D(path, pos=(.02, .02), c='k')) plt.add(boundary_mesh) plt.render() plt = vedo.Plotter(interactive=False) pos, path = getpos(data_idx) pts = vedo.Points(pos, c='b') plt.keyPressFunction = keyfunc data_info = vedo.Text2D(path, pos=(.02, .02), c='k') verts = [(-1.5, 0, -1.5), (-1.5, 0, 1.5), (1.5, 0, 1.5), (1.5, 0, -1.5), (-1.5, 5, -1.5), (-1.5, 5, 1.5), (1.5, 5, 1.5), (1.5, 5, -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)] faces = [(3, 2, 1, 0), (0, 1, 5, 4), (4, 7, 3, 0)] boundary_mesh = vedo.Mesh([verts, faces]).lineColor('black').lineWidth(1) plt += boundary_mesh plt += pts plt += data_info plt.show() vedo.interactive()
##################################################### vedo def funcMove(event): mesh = event.actor if not mesh: return ptid = mesh.closestPoint(event.picked3d, returnPointId=True) txt = f"Probed point:\n{vedo.utils.precision(event.picked3d, 3)}\n" \ f"value = {vedo.utils.precision(arr[ptid], 2)}" vpt = vedo.shapes.Sphere(mesh.points(ptid), r=0.01, c='orange2').pickable(False) vig = vpt.vignette(txt, s=.05, offset=(0.5,0.5), font="VictorMono").followCamera() msg.text(txt) # update the 2d text message plt.remove(plt.actors[-2:]).add([vpt, vig]) # remove last 2 objects, add the new ones widget.Render() # need to manually call Render msg = vedo.Text2D(pos='bottom-left', font="VictorMono") msh = vedo.shapes.ParametricShape("RandomHills").cmap('terrain') axs = vedo.Axes(msh) arr = msh.pointdata["Scalars"] plt = vedo.Plotter(bg='moccasin', bg2='blue9', wxWidget=widget) plt.add([msh, axs, msg]).resetCamera() plt.actors += [None,None,None] # place holder for sphere, vignette, text2d plt.addCallback('MouseMove', funcMove) ##################################################### # Show everything frame.Show() app.MainLoop()