def show_dem3d(self, dem): nr, nc = len(dem.y), len(dem.x) triangle_indices = np.empty((nr - 1, nc - 1, 2, 3), dtype='uint32') r = np.arange(nr * nc, dtype='uint32').reshape(nr, nc) triangle_indices[:, :, 0, 0] = r[:-1, :-1] triangle_indices[:, :, 1, 0] = r[:-1, 1:] triangle_indices[:, :, 0, 1] = r[:-1, 1:] triangle_indices[:, :, 1, 1] = r[1:, 1:] triangle_indices[:, :, :, 2] = r[1:, :-1, None] triangle_indices.shape = (-1, 3) height_component = Component(name='value', array=self.alt) mesh = PolyMesh(vertices=self.vertices, triangle_indices=triangle_indices, data={'height': [height_component]}) colored_mesh = IsoColor(mesh, input='height', min=np.min(self.alt), max=np.max(self.alt)) warped_mesh = Warp(colored_mesh, input=(0, 0, ('height', 'value')), factor=0) warp_slider = FloatSlider(min=0, max=10, value=0, description='Vertical exaggeration', style={'description_width': 'initial'}) jslink((warped_mesh, 'factor'), (warp_slider, 'value')) self.dem3d.clear_output() with self.dem3d: display(VBox((Scene([warped_mesh]), warp_slider)))
def test_default_input(): vertices, triangles, data_1d, data_3d = get_test_assets() poly = PolyMesh(vertices=vertices, triangle_indices=triangles, data=[data_1d, data_3d]) colored_mesh = IsoColor(poly) assert colored_mesh.input == '1d' poly = PolyMesh(vertices=vertices, triangle_indices=triangles, data=[data_3d]) colored_mesh = IsoColor(poly) assert colored_mesh.input == (('3d', 'x'), )
def ipygany_block_from_actor(actor): """Convert a vtk actor to a ipygany Block.""" mapper = actor.GetMapper() if mapper is None: return dataset = mapper.GetInputAsDataSet() prop = actor.GetProperty() rep_type = prop.GetRepresentationAsString() # check if missing faces as a polydata if rep_type != 'Points' and isinstance(dataset, pv.PolyData): if not dataset.faces.size and dataset.n_points: rep_type = 'Points' if rep_type == 'Points': pmesh = pyvista_object_to_pointcloud(dataset) elif rep_type == 'Wireframe': warnings.warn('Wireframe style is not supported in ipygany') return else: pmesh = pyvista_polydata_to_polymesh(dataset) pmesh.default_color = color_float_to_hex(*prop.GetColor()) # determine if there are active scalars valid_mode = mapper.GetScalarModeAsString() in [ 'UsePointData', 'UseCellData' ] if valid_mode: # verify dataset is in pmesh names = [dataset.name for dataset in pmesh.data] if dataset.active_scalars_name in names: mn, mx = mapper.GetScalarRange() cmesh = IsoColor(pmesh, input=dataset.active_scalars_name, min=mn, max=mx) if hasattr(mapper, 'cmap'): cmap = check_colormap(mapper.cmap) cmesh.colormap = colormaps[cmap] return cmesh return pmesh
def test_colormaps(): vertices, triangles, data_1d, data_3d = get_test_assets() poly = PolyMesh(vertices=vertices, triangle_indices=triangles, data=[data_1d, data_3d]) colored_mesh = IsoColor(poly, colormap='Turbo') assert colored_mesh.colormap == colormaps.Turbo colormap = colormaps.Cividis colored_mesh.colormap = colormap assert colored_mesh.colormap == colormap with pytest.raises(ValueError): colored_mesh.colormap = 'InvalidColor' with pytest.raises(ValueError): colored_mesh.colormap = -1
def setup(self): vertices, triangle_indices = self.dataset._widgets.to_unstructured_mesh() elev_da = self.dataset._widgets.elevation elev_min = elev_da.min() elev_max = elev_da.max() elev_arr = self.dataset._widgets.current_elevation.values data = { 'color': [Component(name='value', array=elev_arr, min=elev_min, max=elev_max)], 'warp': [Component(name='value', array=elev_arr, min=elev_min, max=elev_max)], } self.polymesh = PolyMesh(vertices=vertices, triangle_indices=triangle_indices, data=data) self.isocolor = IsoColor( self.polymesh, input=('color', 'value'), min=elev_min, max=elev_max ) self.warp = WarpByScalar(self.isocolor, input='warp', factor=1) self.scene = Scene([self.warp]) return self.scene
# In[1]: import numpy as np import pyvista as pv from ipywidgets import FloatSlider, FloatRangeSlider, Dropdown, Select, Box, AppLayout, jslink, Layout, VBox, HBox from ipygany import Scene, IsoColor, TetraMesh, Component, ColorBar, colormaps mesh = TetraMesh.from_vtk( 'benchmarks/004-eliptic-membrane/eliptic-membrane.vtu', show_edges=True) sigmayy_min = -3.4e7 sigmayy_max = 9.3e7 # Colorize by height colored_mesh = IsoColor(mesh, input=('S', 'YY'), min=sigmayy_min, max=sigmayy_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[sigmayy_min, sigmayy_max], min=sigmayy_min, max=sigmayy_max, step=(sigmayy_max - sigmayy_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance if zoom == 'tight': zoom=1 # disable it if isinstance(vp.shape, str) or sum(vp.shape) > 2: colors.printc("Multirendering is not supported in jupyter.", c=1) return #################################################################################### # https://github.com/InsightSoftwareConsortium/itkwidgets # /blob/master/itkwidgets/widget_viewer.py if 'itk' in settings.notebookBackend: from itkwidgets import view settings.notebook_plotter = view(actors=actors2show, cmap='jet', ui_collapsed=True, gradient_opacity=False) #################################################################################### elif settings.notebookBackend == 'k3d': try: import k3d # https://github.com/K3D-tools/K3D-jupyter except: print("Cannot find k3d, install with: pip install k3d") return actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vtk.vtkAssembly): #unpack assemblies acass = ia.unpack() actors2show2 += acass else: actors2show2.append(ia) # vbb, sizes, _, _ = addons.computeVisibleBounds() # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=settings.k3dMenuVisibility, height=settings.k3dPlotHeight, antialias=settings.k3dAntialias, ) # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = settings.k3dLighting # set k3d camera settings.notebook_plotter.camera_auto_fit = settings.k3dCameraAutoFit settings.notebook_plotter.grid_auto_fit = settings.k3dGridAutoFit settings.notebook_plotter.axes_helper = settings.k3dAxesHelper if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) if zoom: k3dc[0] /= zoom k3dc[1] /= zoom k3dc[2] /= zoom settings.notebook_plotter.camera = k3dc # else: # vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] # vss = numpy.linalg.norm([vsx, vsy, vsz]) # if zoom: # vss /= zoom # vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target # if viewup == 'z': # vup = (0,0,1) # camera up vector # vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position # elif viewup == 'x': # vup = (1,0,0) # vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position # else: # vup = (0,1,0) # vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position # settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], # vfp[0], vfp[1], vfp[2], # vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False for ia in actors2show2: if isinstance(ia, (vtk.vtkCornerAnnotation, vtk.vtkAssembly)): continue kobj = None kcmap= None name = None if hasattr(ia, 'filename'): if ia.filename: name = os.path.basename(ia.filename) if ia.name: name = os.path.basename(ia.name) #####################################################################scalars # work out scalars first, Points Lines are also Mesh objs if isinstance(ia, (Mesh, shapes.Line, Points)): # print('scalars', ia.name, ia.N()) iap = ia.GetProperty() if isinstance(ia, (shapes.Line, Points)): iapoly = ia.polydata() else: iapoly = ia.clone().clean().triangulate().computeNormals().polydata() vtkscals = None color_attribute = None if ia.mapper().GetScalarVisibility(): vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is None: vtkdata = iapoly.GetCellData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(iapoly) c2p.Update() iapoly = c2p.GetOutput() vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: if not vtkscals.GetName(): vtkscals.SetName('scalars') scals_min, scals_max = ia.mapper().GetScalarRange() color_attribute = (vtkscals.GetName(), scals_min, scals_max) lut = ia.mapper().GetLookupTable() lut.Build() kcmap=[] nlut = lut.GetNumberOfTableValues() for i in range(nlut): r,g,b,a = lut.GetTableValue(i) kcmap += [i/(nlut-1), r,g,b] #####################################################################Volume if isinstance(ia, Volume): # print('Volume', ia.name, ia.dimensions()) kx, ky, kz = ia.dimensions() arr = ia.pointdata[0] kimage = arr.reshape(-1, ky, kx) colorTransferFunction = ia.GetProperty().GetRGBTransferFunction() kcmap=[] for i in range(128): r,g,b = colorTransferFunction.GetColor(i/127) kcmap += [i/127, r,g,b] kbounds = numpy.array(ia.imagedata().GetBounds()) \ + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\ * numpy.array([-1,1] * 3) kobj = k3d.volume(kimage.astype(numpy.float32), color_map=kcmap, #color_range=ia.imagedata().GetScalarRange(), alpha_coef=10, bounds=kbounds, name=name, ) settings.notebook_plotter += kobj #####################################################################text elif hasattr(ia, 'info') and 'formula' in ia.info.keys(): pos = (ia.GetPosition()[0],ia.GetPosition()[1]) kobj = k3d.text2d(ia.info['formula'], position=pos) settings.notebook_plotter += kobj #####################################################################Mesh elif isinstance(ia, Mesh) and ia.N() and len(ia.faces()): # print('Mesh', ia.name, ia.N(), len(ia.faces())) kobj = k3d.vtk_poly_data(iapoly, name=name, # color=_rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), wireframe=(iap.GetRepresentation()==1)) if iap.GetInterpolation() == 0: kobj.flat_shading = True settings.notebook_plotter += kobj #####################################################################Points elif isinstance(ia, Points): # print('Points', ia.name, ia.N()) kcols=[] if color_attribute is not None: scals = utils.vtk2numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) kobj = k3d.points(ia.points().astype(numpy.float32), color=_rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader=settings.k3dPointShader, point_size=iap.GetPointSize(), name=name, ) settings.notebook_plotter += kobj #####################################################################Lines elif ia.polydata(False).GetNumberOfLines(): # print('Line', ia.name, ia.N(), len(ia.faces()), # ia.polydata(False).GetNumberOfLines(), len(ia.lines()), # color_attribute, [vtkscals]) # kcols=[] # if color_attribute is not None: # scals = utils.vtk2numpy(vtkscals) # kcols = k3d.helpers.map_colors(scals, kcmap, # [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) for i, ln_idx in enumerate(ia.lines()): if i>200: print('WARNING: K3D nr of line segments is limited to 200.') break pts = ia.points()[ln_idx] kobj = k3d.line(pts.astype(numpy.float32), color=_rgb2int(iap.GetColor()), opacity=iap.GetOpacity(), shader=settings.k3dLineShader, # width=iap.GetLineWidth()*sqsize/1000, name=name, ) settings.notebook_plotter += kobj #################################################################################### elif settings.notebookBackend == 'panel' and hasattr(vp, 'window') and vp.window: import panel # https://panel.pyviz.org/reference/panes/VTK.html vp.renderer.ResetCamera() settings.notebook_plotter = panel.pane.VTK(vp.window, width=int(vp.size[0]/1.5), height=int(vp.size[1]/2)) #################################################################################### elif 'ipyvtk' in settings.notebookBackend and hasattr(vp, 'window') and vp.window: from ipyvtklink.viewer import ViewInteractiveWidget vp.renderer.ResetCamera() settings.notebook_plotter = ViewInteractiveWidget(vp.window) #################################################################################### elif 'ipygany' in settings.notebookBackend: from ipygany import PolyMesh, Scene, IsoColor, RGB, Component from ipygany import Alpha, ColorBar, colormaps, PointCloud from ipywidgets import FloatRangeSlider, Dropdown, VBox, AppLayout, jslink bgcol = colors.rgb2hex(colors.getColor(vp.backgrcol)) actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vedo.Assembly): #unpack assemblies assacts = ia.unpack() for ja in assacts: if isinstance(ja, vedo.Assembly): actors2show2 += ja.unpack() else: actors2show2.append(ja) else: actors2show2.append(ia) pmeshes = [] colorbar = None for obj in actors2show2: # print("ipygany processing:", [obj], obj.name) if isinstance(obj, vedo.shapes.Line): lg = obj.diagonalSize()/1000 * obj.GetProperty().GetLineWidth() vmesh = vedo.shapes.Tube(obj.points(), r=lg, res=4).triangulate() vmesh.c(obj.c()) faces = vmesh.faces() # todo: Lines elif isinstance(obj, Mesh): vmesh = obj.triangulate() faces = vmesh.faces() elif isinstance(obj, Points): vmesh = obj faces = [] elif isinstance(obj, Volume): vmesh = obj.isosurface() faces = vmesh.faces() elif isinstance(obj, vedo.TetMesh): vmesh = obj.tomesh(fill=False) faces = vmesh.faces() else: print("ipygany backend: cannot process object type", [obj]) continue vertices = vmesh.points() scals = vmesh.inputdata().GetPointData().GetScalars() if scals and not colorbar: # there is an active array, only pick the first aname = scals.GetName() arr = vmesh.pointdata[aname] parr = Component(name=aname, array=arr) if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces, data={aname: [parr]}) else: pmesh = PointCloud(vertices=vertices, data={aname: [parr]}) rng = scals.GetRange() colored_pmesh = IsoColor(pmesh, input=aname, min=rng[0], max=rng[1]) if obj.scalarbar: colorbar = ColorBar(colored_pmesh) colormap_slider_range = FloatRangeSlider(value=rng, min=rng[0], max=rng[1], step=(rng[1] - rng[0]) / 100.) jslink((colored_pmesh, 'range'), (colormap_slider_range, 'value')) colormap = Dropdown( options=colormaps, description='Colormap:' ) jslink((colored_pmesh, 'colormap'), (colormap, 'index')) else: if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces) else: pmesh = PointCloud(vertices=vertices) if vmesh.alpha() < 1: colored_pmesh = Alpha(RGB(pmesh, input=tuple(vmesh.color())), input=vmesh.alpha()) else: colored_pmesh = RGB(pmesh, input=tuple(vmesh.color())) pmeshes.append(colored_pmesh) if colorbar: scene = AppLayout( left_sidebar=Scene(pmeshes, background_color=bgcol), right_sidebar=VBox((colormap_slider_range, #not working colorbar, colormap)), pane_widths=[2, 0, 1], ) else: scene = Scene(pmeshes, background_color=bgcol) settings.notebook_plotter = scene #################################################################################### elif '2d' in settings.notebookBackend.lower() and hasattr(vp, 'window') and vp.window: import PIL.Image try: import IPython except ImportError: raise Exception('IPython not available.') from vedo.io import screenshot settings.screeshotLargeImage = True nn = screenshot(returnNumpy=True, scale=settings.screeshotScale+2) pil_img = PIL.Image.fromarray(nn) settings.notebook_plotter = IPython.display.display(pil_img) return settings.notebook_plotter
# In[1]: import numpy as np import pyvista as pv from ipywidgets import FloatSlider, FloatRangeSlider, Dropdown, Select, Box, AppLayout, jslink, Layout, VBox, HBox from ipygany import Scene, IsoColor, TetraMesh, Component, ColorBar, colormaps mesh = TetraMesh.from_vtk( 'benchmarks/005-hemispherical-shell-point-load/hemisperical-shell-points-load.vtu', show_edges=True) u_min = 4.4e-6 u_max = 1.8e-1 # Colorize by height colored_mesh = IsoColor(mesh, input=('u', 'X1'), min=u_min, max=u_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[u_min, u_max], min=u_min, max=u_max, step=(u_max - u_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description='colormap:')
# In[1]: import numpy as np import pyvista as pv from ipywidgets import FloatSlider, FloatRangeSlider, Dropdown, Select, Box, AppLayout, jslink, Layout, VBox, HBox from ipygany import Scene, IsoColor, TetraMesh, Component, ColorBar, colormaps mesh = TetraMesh.from_vtk('benchmarks/002-cook-membrane/elmer.vtu', show_edges=True) dispy_min = 0.0 dispy_max = 32.5 # Colorize by height colored_mesh = IsoColor(mesh, input=('U', 'D2'), min=dispy_min, max=dispy_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[dispy_min, dispy_max], min=dispy_min, max=dispy_max, step=(dispy_max - dispy_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description='colormap:')
def visualize_it(res_file, temp_dir=".temp", default_index=0): import pathlib import meshio from ipygany import ColorBar, IsoColor, PolyMesh, Scene, Warp, colormaps from IPython.display import clear_output, display from ipywidgets import AppLayout, Dropdown, FloatSlider, VBox, jslink from ada.core.vector_utils import vector_length res_file = pathlib.Path(res_file).resolve().absolute() suffix = res_file.suffix.lower() suffix_map = {".rmed": "med", ".vtu": None} imesh = meshio.read(res_file, file_format=suffix_map[suffix]) imesh.point_data = { key.replace(" ", "_"): value for key, value in imesh.point_data.items() } def filter_keys(var): if suffix == ".vtu" and var != "U": return False if suffix == ".rmed" and var == "point_tags": return False return True warp_data = [key for key in filter(filter_keys, imesh.point_data.keys())] magn_data = [] for d in warp_data: res = [vector_length(v[:3]) for v in imesh.point_data[d]] res_norm = [r / max(res) for r in res] magn_data_name = f"{d}_magn" imesh.point_data[magn_data_name] = np.array(res_norm, dtype=np.float64) magn_data.append(magn_data_name) imesh.field_data = { key: np.array(value) for key, value in imesh.field_data.items() } tf = (pathlib.Path(temp_dir).resolve().absolute() / res_file.name).with_suffix(".vtu") if tf.exists(): os.remove(tf) os.makedirs(tf.parent, exist_ok=True) imesh.write(tf) mesh = PolyMesh.from_vtk(str(tf)) mesh.default_color = "gray" warp_vec = warp_data[default_index] try: colored_mesh = IsoColor(mesh, input=magn_data[default_index], min=0.0, max=1.0) except KeyError as e: trace_str = traceback.format_exc() logging.error(f'KeyError "{e}"\nTrace: "{trace_str}"') colored_mesh = mesh except ImportError as e: trace_str = traceback.format_exc() logging.error("This might be") logging.error(f'ImportError "{e}"\nTrace: "{trace_str}"') return warped_mesh = Warp(colored_mesh, input=warp_vec, warp_factor=0.0) warp_slider = FloatSlider(value=0.0, min=-1.0, max=1.0) jslink((warped_mesh, "factor"), (warp_slider, "value")) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description="colormap:") jslink((colored_mesh, "colormap"), (colormap, "index")) # EigenValue choice widget eig_map = Dropdown(options=warp_data, description="Data Value:") scene = Scene([warped_mesh]) app = AppLayout(left_sidebar=scene, right_sidebar=VBox( (eig_map, warp_slider, colormap, colorbar)), pane_widths=[2, 0, 1]) def change_input(change): vec_name = change["new"] logging.info(vec_name) colored_mesh.input = vec_name + "_magn" warped_mesh.input = vec_name # Highly inefficient but likely needed due to bug https://github.com/QuantStack/ipygany/issues/69 clear_output() display(app) eig_map.observe(change_input, names=["value"]) return app
# In[1]: import numpy as np import pyvista as pv from ipywidgets import FloatSlider, FloatRangeSlider, Dropdown, Select, Box, AppLayout, jslink, Layout, VBox, HBox from ipygany import Scene, IsoColor, TetraMesh, Component, ColorBar, colormaps mesh = TetraMesh.from_vtk( 'benchmarks/003-Hertz-contact/very-fine-quad-hex.vtu', show_edges=True) stress_min = 0.0 stress_max = 934 # Colorize by height colored_mesh = IsoColor(mesh, input=('S', 'Mises'), min=stress_min, max=stress_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[stress_min, stress_max], min=stress_min, max=stress_max, step=(stress_max - stress_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description='colormap:')
# In[1]: import numpy as np import pyvista as pv from ipywidgets import FloatSlider, FloatRangeSlider, Dropdown, Select, Box, AppLayout, jslink, Layout, VBox, HBox from ipygany import Scene, IsoColor, TetraMesh, Component, ColorBar, colormaps mesh = TetraMesh.from_vtk('benchmarks/007-raasch-challenge/elmer.vtu', show_edges=True) dispy_min = 0.0 dispy_max = 0.125 # Colorize by height colored_mesh = IsoColor(mesh, input=('u', 'X3'), min=dispy_min, max=dispy_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[dispy_min, dispy_max], min=dispy_min, max=dispy_max, step=(dispy_max - dispy_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description='colormap:')