def exe_convert(args): allowedexts = [ 'vtk', 'vtp', 'vtu', 'vts', 'npy', 'ply', 'stl', 'obj', 'byu', 'xml', 'vti', 'tif', 'mhd', 'xml' ] humansort(args.convert) nfiles = len(args.convert) if nfiles == 0: sys.exit() target_ext = args.to.lower() if target_ext not in allowedexts: printc('Sorry target cannot be', target_ext, '\nMust be', allowedexts, c=1) sys.exit() for f in args.convert: source_ext = f.split('.')[-1] if target_ext == source_ext: continue a = load(f) newf = f.replace("." + source_ext, "") + "." + target_ext a.write(newf, binary=True)
def exe_search(args): expath = os.path.join(settings.installdir, "examples", "**", "*.py") exfiles = [f for f in sorted(glob.glob(expath, recursive=True))] pattern = args.search if args.no_camera_share: pattern = pattern.lower() if len(pattern) > 3: for ifile in exfiles: with open(ifile, "r") as file: fflag = True for i, line in enumerate(file): if args.no_camera_share: bline = line.lower() else: bline = line if pattern in bline: if fflag: name = os.path.basename(ifile) etype = ifile.split("/")[-2] printc("--> examples/" + etype + "/" + name + ":", c='y', italic=1, invert=1) fflag = False line = line.replace( pattern, "\x1b[4m\x1b[1m" + pattern + "\x1b[0m\u001b[33m") print(f"\u001b[33m{i}\t{line}\x1b[0m", end='') # printc(i, line, c='o', bold=False, end='') else: printc("Please specify at least four characters.", c='r')
def rfft(self, mode='magnitude'): """Reverse Fast Fourier transform of a picture.""" ffti = vtk.vtkImageRFFT() ffti.SetInputData(self._data) ffti.Update() if 'mag' in mode: mag = vtk.vtkImageMagnitude() mag.SetInputData(ffti.GetOutput()) mag.Update() out = mag.GetOutput() elif 'real' in mode: extractRealFilter = vtk.vtkImageExtractComponents() extractRealFilter.SetInputData(ffti.GetOutput()) extractRealFilter.SetComponents(0) extractRealFilter.Update() out = extractRealFilter.GetOutput() elif 'imaginary' in mode: extractImgFilter = vtk.vtkImageExtractComponents() extractImgFilter.SetInputData(ffti.GetOutput()) extractImgFilter.SetComponents(1) extractImgFilter.Update() out = extractImgFilter.GetOutput() elif 'complex' in mode: out = ffti.GetOutput() else: colors.printc("Error in rfft(): unknown mode", mode) raise RuntimeError() return Picture(out)
def move(self, u=None, deltas=None): """Move mesh according to solution `u` or from calculated vertex displacements `deltas`. """ if u is None: u = self.u if deltas is None: if self.u_values is not None: deltas = self.u_values else: deltas = _compute_uvalues(u, self.mesh) self.u_values = deltas if hasattr(self.mesh, "coordinates"): coords = self.mesh.coordinates() else: coords = self.mesh.geometry.points if coords.shape != deltas.shape: printc("ERROR: Try to move mesh with wrong solution type shape:", coords.shape, 'vs', deltas.shape, c=1) printc("Mesh is not moved. Try mode='color' in plot().", c=1) return movedpts = coords + deltas if movedpts.shape[1] == 2: #2d movedpts = np.c_[movedpts, np.zeros(movedpts.shape[0])] self.polydata(False).GetPoints().SetData( numpy_to_vtk(np.ascontiguousarray(movedpts))) self._polydata.GetPoints().Modified()
def move(self, act=None, pt=(0, 0, 0), t=None, duration=None, style='linear'): """Smoothly change the position of a specific object to a new point in space.""" if self.bookingMode: acts, t, duration, rng = self._parse(act, t, duration) if len(acts) != 1: printc('Error in move(), can move only one object.', c='r') cpos = acts[0].pos() pt = np.array(pt) dv = (pt - cpos) / len(rng) for j, tt in enumerate(rng): i = j + 1 if 'quad' in style: x = i / len(rng) y = x * x #print(x,y) self.events.append( (tt, self.move, acts, cpos + dv * i * y)) else: self.events.append((tt, self.move, acts, cpos + dv * i)) else: self._performers[0].pos(self._inputvalues) return self
def meshErode(self, act=None, corner=6, t=None, duration=None): """Erode a mesh by removing cells that are close to one of the 8 corners of the bounding box. """ if self.bookingMode: acts, t, duration, rng = self._parse(act, t, duration) if len(acts) != 1: printc('Error in meshErode(), can erode only one object.', c='r') diag = acts[0].diagonalSize() x0, x1, y0, y1, z0, z1 = acts[0].GetBounds() corners = [(x0, y0, z0), (x1, y0, z0), (x1, y1, z0), (x0, y1, z0), (x0, y0, z1), (x1, y0, z1), (x1, y1, z1), (x0, y1, z1)] pcl = acts[0].closestPoint(corners[corner]) dmin = np.linalg.norm(pcl - corners[corner]) for tt in rng: d = linInterpolate(tt, [t, t + duration], [dmin, diag * 1.01]) if d > 0: ids = acts[0].closestPoint(corners[corner], radius=d, returnPointId=True) if len(ids) <= acts[0].N(): self.events.append((tt, self.meshErode, acts, ids)) else: self._performers[0].deletePoints(self._inputvalues) return self
def mirror(self, axis="x"): """ Mirror flip along one of the cartesian axes. .. note:: ``axis='n'``, will flip only mesh normals. |mirror| |mirror.py|_ """ img = self.imagedata() ff = vtk.vtkImageFlip() ff.SetInputData(img) if axis.lower() == "x": ff.SetFilteredAxis(0) elif axis.lower() == "y": ff.SetFilteredAxis(1) elif axis.lower() == "z": ff.SetFilteredAxis(2) else: colors.printc( "\times Error in mirror(): mirror must be set to x, y, z or n.", c='r') raise RuntimeError() ff.Update() return self._update(ff.GetOutput())
def __init__(self, obj=None): vtk.vtkImageActor.__init__(self) Base3DProp.__init__(self) if utils.isSequence(obj) and len(obj): iac = vtk.vtkImageAppendComponents() nchan = obj.shape[ 2] # get number of channels in inputimage (L/LA/RGB/RGBA) for i in range(nchan): #arr = np.flip(np.flip(array[:,:,i], 0), 0).ravel() arr = np.flip(obj[:, :, i], 0).ravel() varb = numpy_to_vtk(arr, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) imgb = vtk.vtkImageData() imgb.SetDimensions(obj.shape[1], obj.shape[0], 1) imgb.GetPointData().SetScalars(varb) iac.AddInputData(0, imgb) iac.Update() img = iac.GetOutput() self.SetInputData(img) elif isinstance(obj, vtk.vtkImageData): self.SetInputData(obj) img = obj elif isinstance(obj, str): if "https://" in obj: import vedo.io as io obj = io.download(obj, verbose=False) if ".png" in obj: picr = vtk.vtkPNGReader() elif ".jpg" in obj or ".jpeg" in obj: picr = vtk.vtkJPEGReader() elif ".bmp" in obj: picr = vtk.vtkBMPReader() elif ".tif" in obj: picr = vtk.vtkTIFFReader() else: colors.printc("Cannot understand picture format", obj, c='r') return picr.SetFileName(obj) self.filename = obj picr.Update() img = picr.GetOutput() self.SetInputData(img) else: img = vtk.vtkImageData() self.SetInputData(img) self._data = img sx, sy, _ = img.GetDimensions() self.shape = np.array([sx, sy]) self._mapper = self.GetMapper()
def __init__(self, obj=None, channels=(), flip=False): vtk.vtkImageActor.__init__(self) vedo.base.Base3DProp.__init__(self) if utils.isSequence(obj) and len(obj): # passing array img = _get_img(obj, flip) elif isinstance(obj, vtk.vtkImageData): img = obj elif isinstance(obj, str): if "https://" in obj: obj = vedo.io.download(obj, verbose=False) fname = obj.lower() if fname.endswith(".png"): picr = vtk.vtkPNGReader() elif fname.endswith(".jpg") or fname.endswith(".jpeg"): picr = vtk.vtkJPEGReader() elif fname.endswith(".bmp"): picr = vtk.vtkBMPReader() elif fname.endswith(".tif") or fname.endswith(".tiff"): picr = vtk.vtkTIFFReader() picr.SetOrientationType(vedo.settings.tiffOrientationType) else: colors.printc("Cannot understand picture format", obj, c='r') return picr.SetFileName(obj) self.filename = obj picr.Update() img = picr.GetOutput() else: img = vtk.vtkImageData() # select channels nchans = len(channels) if nchans and img.GetPointData().GetScalars().GetNumberOfComponents() > nchans: pec = vtk.vtkImageExtractComponents() pec.SetInputData(img) if nchans == 3: pec.SetComponents(channels[0], channels[1], channels[2]) elif nchans == 2: pec.SetComponents(channels[0], channels[1]) elif nchans == 1: pec.SetComponents(channels[0]) pec.Update() img = pec.GetOutput() self._data = img self.SetInputData(img) sx,sy,_ = img.GetDimensions() self.shape = np.array([sx,sy]) self._mapper = self.GetMapper()
def Slicer2d(volume, size=(900, 900), bg=(0.6, 0.6, 0.7), zoom=1.3): """Create a 2D window with a single balck a nd white slice of a Volume, wich can be oriented arbitrarily in space. """ img = volume.imagedata() ren1 = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren1) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) im = vtk.vtkImageResliceMapper() im.SetInputData(img) im.SliceFacesCameraOn() im.SliceAtFocalPointOn() im.BorderOn() ip = vtk.vtkImageProperty() ip.SetInterpolationTypeToLinear() ia = vtk.vtkImageSlice() ia.SetMapper(im) ia.SetProperty(ip) ren1.AddViewProp(ia) ren1.SetBackground(bg) renWin.SetSize(size) iren = vtk.vtkRenderWindowInteractor() style = vtk.vtkInteractorStyleImage() style.SetInteractionModeToImage3D() iren.SetInteractorStyle(style) renWin.SetInteractor(iren) renWin.Render() cam1 = ren1.GetActiveCamera() cam1.ParallelProjectionOn() ren1.ResetCameraClippingRange() cam1.Zoom(zoom) renWin.Render() printc("Slicer2D tool", invert=1, c="m") printc( """Press SHIFT+Left mouse to rotate the camera for oblique slicing SHIFT+Middle mouse to slice perpendicularly through the image Left mouse and Drag to modify luminosity and contrast X to Reset to sagittal view Y to Reset to coronal view Z to Reset to axial view R to Reset the Window/Levels Q to Quit.""", c="m", ) iren.Start() return iren
def _compute_uvalues(u, mesh): # the whole purpose of this function is # to have a scalar (or vector) for each point of the mesh if not u: return # print('u',u) if hasattr(u, 'compute_vertex_values'): # old dolfin, works fine u_values = u.compute_vertex_values(mesh) if u.value_rank() and u.value_dimension(0) > 1: l = u_values.shape[0] u_values = u_values.reshape(u.value_dimension(0), int(l / u.value_dimension(0))).T elif hasattr(u, 'compute_point_values'): # dolfinx u_values = u.compute_point_values() try: from dolfin import fem fvec = u.vector except RuntimeError: fspace = u.function_space try: fspace = fspace.collapse() except RuntimeError: return [] fvec = fem.interpolate(u, fspace).vector tdim = mesh.topology.dim #print('fvec.getSize', fvec.getSize(), mesh.num_entities(tdim)) if fvec.getSize() == mesh.num_entities(tdim): # DG0 cellwise function C = fvec.get_local() if (C.dtype.type is np.complex128): print("Plotting real part of complex data") C = np.real(C) u_values = C else: u_values = [] if hasattr(mesh, "coordinates"): coords = mesh.coordinates() else: coords = mesh.geometry.points if u_values.shape[0] != coords.shape[0]: printc('Warning: mismatch in vedo.dolfin._compute_uvalues()', c=1) u_values = np.array([u(p) for p in coords]) return u_values
def fft(self, mode='magnitude', logscale=12, center=True): """Fast Fourier transform of a picture. :param float logscale: if non-zero, take the logarithm of the intensity and scale it by this factor. :param str mode: either [magnitude, real, imaginary, complex], compute the point array data accordingly. :param bool center: shift constant zero-frequency to the center of the image for display. (FFT converts spatial images into frequency space, but puts the zero frequency at the origin) """ ffti = vtk.vtkImageFFT() ffti.SetInputData(self._data) ffti.Update() if 'mag' in mode: mag = vtk.vtkImageMagnitude() mag.SetInputData(ffti.GetOutput()) mag.Update() out = mag.GetOutput() elif 'real' in mode: extractRealFilter = vtk.vtkImageExtractComponents() extractRealFilter.SetInputData(ffti.GetOutput()) extractRealFilter.SetComponents(0) extractRealFilter.Update() out = extractRealFilter.GetOutput() elif 'imaginary' in mode: extractImgFilter = vtk.vtkImageExtractComponents() extractImgFilter.SetInputData(ffti.GetOutput()) extractImgFilter.SetComponents(1) extractImgFilter.Update() out = extractImgFilter.GetOutput() elif 'complex' in mode: out = ffti.GetOutput() else: colors.printc("Error in fft(): unknown mode", mode) raise RuntimeError() if center: center = vtk.vtkImageFourierCenter() center.SetInputData(out) center.Update() out = center.GetOutput() if 'complex' not in mode: if logscale: ils = vtk.vtkImageLogarithmicScale() ils.SetInputData(out) ils.SetConstant(logscale) ils.Update() out = ils.GetOutput() return Picture(out)
def mirror(self, axis="x"): """Mirror picture along x or y axis. Same as flip().""" ff = vtk.vtkImageFlip() ff.SetInputData(self.inputdata()) if axis.lower() == "x": ff.SetFilteredAxis(0) elif axis.lower() == "y": ff.SetFilteredAxis(1) else: colors.printc("Error in mirror(): mirror must be set to x or y.", c='r') raise RuntimeError() ff.Update() return self._update(ff.GetOutput())
def threshold(self, name=None, above=None, below=None, on='cells'): """ Threshold the tetrahedral mesh by a cell scalar value. Reduce to only tets which satisfy the threshold limits. If ``above==below`` will only select tets with that specific value. If ``above > below`` selection range is "flipped" (vtk_version>8). :param str on: either name refers to a "cells or "points" array. """ th = vtk.vtkThreshold() th.SetInputData(self._data) if name is None: ns = self.getArrayNames() if len(ns['CellData']): name = ns['CellData'][0] th.SetInputArrayToProcess(0, 0, 0, 1, name) elif len(ns['PointData']): name = ns['PointData'][0] th.SetInputArrayToProcess(0, 0, 0, 0, name) if name is None: printc("threshold(): Cannot find active array. Skip.", c='r') return self else: if on.startswith('c'): th.SetInputArrayToProcess(0, 0, 0, 1, name) else: th.SetInputArrayToProcess(0, 0, 0, 0, name) if above is not None and below is not None: if above > below: if vedo.settings.vtk_version[0] >= 9: th.SetInvert(True) th.ThresholdBetween(below, above) else: printc( "threshold(): in vtk<9, above cannot be larger than below. Skip.", c='r') return self else: th.ThresholdBetween(above, below) elif above is not None: th.ThresholdByUpper(above) elif below is not None: th.ThresholdByLower(below) th.Update() return self._update(th.GetOutput())
def __init__( self, mesh, splined=True, font="Bongas", alpha=0.9, lw=4, lc="red5", pc="red4", c="green3", tc="k9", tol=0.008, ): if not isinstance(mesh, Points): printc("FreeHandCutPlotter input must be Points or Mesh.", c='r') raise RuntimeError() Plotter.__init__(self, title="Free-hand mesh cutter") self.mesh = mesh self.mesh_prev = mesh self.splined = splined self.linecolor = lc self.linewidth = lw self.pointcolor = pc self.color = c self.alpha = alpha self.msg = "Right-click and move to draw line\n" self.msg += "Second right-click to stop drawing\n" self.msg += "Press L to extract largest surface\n" self.msg += " z/Z to cut mesh (s to save)\n" self.msg += " c to clear points, u to undo" self.txt2d = Text2D(self.msg, pos='top-left', font=font, s=0.9) self.txt2d.c(tc).background(c, alpha).frame() self.idkeypress = self.addCallback('KeyPress', self._onKeyPress) self.idrightclck = self.addCallback('RightButton', self._onRightClick) self.idmousemove = self.addCallback('MouseMove', self._onMouseMove) self.drawmode = False self.tol = tol # tolerance of point distance self.cpoints = [] self.points = None self.spline = None self.jline = None self.topline = None self.top_pts = []
def Browser(meshes, sliderpos=((0.55, 0.07), (0.96, 0.07)), c=None): """ 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(tx) #printc("Browser Mode", c="y", invert=1, end="") #if tx: # printc(": showing #", k, tx, " "*abs(40-len(tx))+"\r", # c="y", bold=0, end="") printc("Browser Mode", 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 return vp
def __init__(self, obj=None): vtk.vtkImageActor.__init__(self) Base3DProp.__init__(self) if utils.isSequence(obj) and len(obj): iac = vtk.vtkImageAppendComponents() for i in range(3): #arr = np.flip(np.flip(array[:,:,i], 0), 0).ravel() arr = np.flip(obj[:, :, i], 0).ravel() varb = numpy_to_vtk(arr, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) imgb = vtk.vtkImageData() imgb.SetDimensions(obj.shape[1], obj.shape[0], 1) imgb.GetPointData().SetScalars(varb) iac.AddInputData(0, imgb) iac.Update() img = iac.GetOutput() self.SetInputData(img) elif isinstance(obj, vtk.vtkImageData): self.SetInputData(obj) img = obj elif isinstance(obj, str): if ".png" in obj: picr = vtk.vtkPNGReader() elif ".jpg" in obj or ".jpeg" in obj: picr = vtk.vtkJPEGReader() elif ".bmp" in obj: picr = vtk.vtkBMPReader() elif ".tif" in obj: picr = vtk.vtkTIFFReader() else: colors.printc("Cannot understand picture format", obj, c=1) picr.SetFileName(obj) picr.Update() img = picr.GetOutput() self.SetInputData(img) else: img = vtk.vtkImageData() self.SetInputData(img) self._data = img self._mapper = self.GetMapper()
def MeshLines(*inputobj, **options): """ Build the line segments between two lists of points `startPoints` and `endPoints`. `startPoints` can be also passed in the form ``[[point1, point2], ...]``. A dolfin ``Mesh`` that was deformed/modified by a function can be passed together as inputs. :param float scale: apply a rescaling factor to the length """ scale = options.pop("scale", 1) lw = options.pop("lw", 1) c = options.pop("c", 'grey') alpha = options.pop("alpha", 1) mesh, u = _inputsort(inputobj) if not mesh: return None if hasattr(mesh, "coordinates"): startPoints = mesh.coordinates() else: startPoints = mesh.geometry.points u_values = _compute_uvalues(u, mesh) if not utils.isSequence(u_values[0]): printc("~times Error: cannot show Lines for 1D scalar values!", c=1) raise RuntimeError() endPoints = startPoints + u_values if u_values.shape[1] == 2: # u_values is 2D u_values = np.insert(u_values, 2, 0, axis=1) # make it 3d startPoints = np.insert(startPoints, 2, 0, axis=1) # make it 3d endPoints = np.insert(endPoints, 2, 0, axis=1) # make it 3d actor = shapes.Lines(startPoints, endPoints, scale=scale, lw=lw, c=c, alpha=alpha) actor.mesh = mesh actor.u = u actor.u_values = u_values return actor
def threshold(self, above=None, below=None, replace=None, replaceOut=None): """ Binary or continuous volume thresholding. Find the voxels that contain a value above/below the input values and replace them with a new value (default is 0). """ th = vtk.vtkImageThreshold() th.SetInputData(self.imagedata()) # sanity checks if above is not None and below is not None: if above == below: return self if above > below: colors.printc( "Warning in volume.threshold(): above > below, skip.", c='y') return self ## cases if below is not None and above is not None: th.ThresholdBetween(above, below) elif above is not None: th.ThresholdByUpper(above) elif below is not None: th.ThresholdByLower(below) ## if replace is not None: th.SetReplaceIn(True) th.SetInValue(replace) else: th.SetReplaceIn(False) if replaceOut is not None: th.SetReplaceOut(True) th.SetOutValue(replaceOut) else: th.SetReplaceOut(False) th.Update() out = th.GetOutput() return self._update(out)
def rotate(self, act=None, axis=(1, 0, 0), angle=0, t=None, duration=None): """Smoothly rotate a specific object by a specified angle and axis.""" if self.bookingMode: acts, t, duration, rng = self._parse(act, t, duration) if len(acts) != 1: printc('Error in rotate(), can move only one object.', c='r') for tt in rng: ang = angle / len(rng) self.events.append((tt, self.rotate, acts, (axis, ang))) else: ax = self._inputvalues[0] if ax == 'x': self._performers[0].rotateX(self._inputvalues[1]) elif ax == 'y': self._performers[0].rotateY(self._inputvalues[1]) elif ax == 'z': self._performers[0].rotateZ(self._inputvalues[1]) return self
def MeshArrows(*inputobj, **options): """ Build arrows representing displacements. :param float s: cross-section size of the arrow :param float rescale: apply a rescaling factor to the length """ s = options.pop("s", None) scale = options.pop("scale", 1) c = options.pop("c", "gray") alpha = options.pop("alpha", 1) res = options.pop("res", 12) mesh, u = _inputsort(inputobj) if not mesh: return None if hasattr(mesh, "coordinates"): startPoints = mesh.coordinates() else: startPoints = mesh.geometry.points u_values = _compute_uvalues(u, mesh) if not utils.isSequence(u_values[0]): printc("~times Error: cannot show Arrows for 1D scalar values!", c=1) raise RuntimeError() endPoints = startPoints + u_values if u_values.shape[1] == 2: # u_values is 2D u_values = np.insert(u_values, 2, 0, axis=1) # make it 3d startPoints = np.insert(startPoints, 2, 0, axis=1) # make it 3d endPoints = np.insert(endPoints, 2, 0, axis=1) # make it 3d actor = shapes.Arrows(startPoints, endPoints, s=s, scale=scale, alpha=alpha, res=res) actor.color(c) actor.mesh = mesh actor.u = u actor.u_values = u_values return actor
def procrustesAlignment(sources, rigid=False): """ Return an ``Assembly`` of aligned source meshes with the `Procrustes` algorithm. The output ``Assembly`` is normalized in size. `Procrustes` algorithm takes N set of points and aligns them in a least-squares sense to their mutual mean. The algorithm is iterated until convergence, as the mean must be recomputed after each alignment. The set of average points generated by the algorithm can be accessed with ``algoutput.info['mean']`` as a numpy array. :param bool rigid: if `True` scaling is disabled. |align3| |align3.py|_ """ from vedo.mesh import Mesh group = vtk.vtkMultiBlockDataGroupFilter() for source in sources: if sources[0].N() != source.N(): colors.printc("Error in procrustesAlignment():", c='r') colors.printc(" sources have different nr of points", c='r') raise RuntimeError() group.AddInputData(source.polydata()) procrustes = vtk.vtkProcrustesAlignmentFilter() procrustes.StartFromCentroidOn() procrustes.SetInputConnection(group.GetOutputPort()) if rigid: procrustes.GetLandmarkTransform().SetModeToRigidBody() procrustes.Update() acts = [] for i, s in enumerate(sources): poly = procrustes.GetOutput().GetBlock(i) mesh = Mesh(poly) mesh.SetProperty(s.GetProperty()) if hasattr(s, 'name'): mesh.name = s.name mesh.flagText = s.flagText acts.append(mesh) assem = Assembly(acts) assem.transform = procrustes.GetLandmarkTransform() assem.info['mean'] = vtk_to_numpy(procrustes.GetMeanPoints().GetData()) return assem
def changeLighting(self, style, acts=None, t=None, duration=None): """Gradually change the lighting style for the input list of meshes. Allowed styles are: [metallic, plastic, shiny, glossy, default]. """ if self.bookingMode: acts, t, duration, rng = self._parse(acts, t, duration) c = (1, 1, 0.99) if style == 'metallic': pars = [0.1, 0.3, 1.0, 10, c] elif style == 'plastic': pars = [0.3, 0.4, 0.3, 5, c] elif style == 'shiny': pars = [0.2, 0.6, 0.8, 50, c] elif style == 'glossy': pars = [0.1, 0.7, 0.9, 90, c] elif style == 'default': pars = [0.1, 1.0, 0.05, 5, c] else: printc('Unknown lighting style:', [style], c='r') for tt in rng: inputvalues = [] for a in acts: pr = a.GetProperty() aa = pr.GetAmbient() ad = pr.GetDiffuse() asp = pr.GetSpecular() aspp = pr.GetSpecularPower() naa = linInterpolate(tt, [t, t + duration], [aa, pars[0]]) nad = linInterpolate(tt, [t, t + duration], [ad, pars[1]]) nasp = linInterpolate(tt, [t, t + duration], [asp, pars[2]]) naspp = linInterpolate(tt, [t, t + duration], [aspp, pars[3]]) inputvalues.append((naa, nad, nasp, naspp)) self.events.append( (tt, self.changeLighting, acts, inputvalues)) else: for i, a in enumerate(self._performers): pr = a.GetProperty() vals = self._inputvalues[i] pr.SetAmbient(vals[0]) pr.SetDiffuse(vals[1]) pr.SetSpecular(vals[2]) pr.SetSpecularPower(vals[3]) return self
def mode(self, mode=None): """Define the volumetric rendering style. - 0, composite rendering - 1, maximum projection rendering - 2, minimum projection rendering - 3, average projection rendering - 4, additive mode """ if mode is None: return self._mapper.GetBlendMode() if isinstance(mode, str): if 'comp' in mode: mode = 0 elif 'proj' in mode: if 'max' in mode: mode = 1 elif 'min' in mode: mode = 2 elif 'ave' in mode: mode = 3 else: colors.printc("Error in volume.mode(): unknown mode", mode, c='r') mode = 0 elif 'add' in mode: mode = 4 else: colors.printc("Error in volume.mode(): unknown mode", mode, c='r') mode = 0 volumeProperty = self.GetProperty() self._mapper.SetBlendMode(mode) self._mode = mode if mode == 0: volumeProperty.ShadeOn() self.lighting('shiny') self.jittering(True) elif mode == 1: volumeProperty.ShadeOff() self.jittering(True) return self
def _parse(self, objs, t, duration): if t is None: if self._lastT: t = self._lastT else: t = 0.0 if duration is None: if self._lastDuration: duration = self._lastDuration else: duration = 0.0 if objs is None: if self._lastActs: objs = self._lastActs else: printc('Need to specify actors!', c='r') raise RuntimeError objs2 = objs if isSequence(objs): objs2 = objs else: objs2 = [objs] #quantize time steps and duration t = int(t / self.timeResolution + 0.5) * self.timeResolution nsteps = int(duration / self.timeResolution + 0.5) duration = nsteps * self.timeResolution rng = np.linspace(t, t + duration, nsteps + 1) self._lastT = t self._lastDuration = duration self._lastActs = objs2 for a in objs2: if a not in self.actors: self.actors.append(a) return objs2, t, duration, rng
def threshold(self, name=None, above=None, below=None): """ Threshold the tetrahedral mesh by a cell scalar value. Reduce to only tets which satisfy the threshold limits. """ th = vtk.vtkThreshold() th.SetInputData(self._data) ns = self.getArrayNames() if name is None: if len(ns['CellData']): name = ns['CellData'][0] th.SetInputArrayToProcess(0, 0, 0, 1, name) elif len(ns['PointData']): name = ns['PointData'][0] th.SetInputArrayToProcess(0, 0, 0, 0, name) if name is None: printc("threshold(): Cannot find active array. Skip.", c='r') return self else: if self.useCells: th.SetInputArrayToProcess(0, 0, 0, 1, name) else: th.SetInputArrayToProcess(0, 0, 0, 0, name) if above is not None and below is not None: if above < below: th.ThresholdBetween(above, below) elif above == below: return self elif above is not None: th.ThresholdByUpper(above) elif below is not None: th.ThresholdByLower(below) th.Update() ugrid = th.GetOutput() return self._update(ugrid)
def moveCamera(self, camstart=None, camstop=None, t=None, duration=None): """ Smoothly move camera between two ``vtkCamera`` objects. """ if self.bookingMode: if camstart is None: if not self.camera: printc("Error in moveCamera(), no camera exists.") return camstart = self.camera acts, t, duration, rng = self._parse(None, t, duration) p1 = np.array(camstart.GetPosition()) f1 = np.array(camstart.GetFocalPoint()) v1 = np.array(camstart.GetViewUp()) c1 = np.array(camstart.GetClippingRange()) s1 = camstart.GetDistance() p2 = np.array(camstop.GetPosition()) f2 = np.array(camstop.GetFocalPoint()) v2 = np.array(camstop.GetViewUp()) c2 = np.array(camstop.GetClippingRange()) s2 = camstop.GetDistance() for tt in rng: np1 = linInterpolate(tt, [t, t + duration], [p1, p2]) nf1 = linInterpolate(tt, [t, t + duration], [f1, f2]) nv1 = linInterpolate(tt, [t, t + duration], [v1, v2]) nc1 = linInterpolate(tt, [t, t + duration], [c1, c2]) ns1 = linInterpolate(tt, [t, t + duration], [s1, s2]) inps = (np1, nf1, nv1, nc1, ns1) self.events.append((tt, self.moveCamera, acts, inps)) else: if not self.camera: return np1, nf1, nv1, nc1, ns1 = self._inputvalues self.camera.SetPosition(np1) self.camera.SetFocalPoint(nf1) self.camera.SetViewUp(nv1) self.camera.SetClippingRange(nc1) self.camera.SetDistance(ns1)
def threshold(self, above=None, below=None, replace=None, replaceOut=None): """ Binary or continuous volume thresholding. Find the voxels that contain a value above/below the input values and replace them with a new value (default is 0). """ th = vtk.vtkImageThreshold() th.SetInputData(self.imagedata()) if above is not None and below is not None: if above==below: return self elif above > below: colors.printc("Error in volume.threshold(): above > below, skip.", c='r') return self th.ThresholdBetween(above, below) elif above is not None: th.ThresholdByUpper(above) elif below is not None: th.ThresholdByLower(below) th.SetReplaceIn(False) th.SetReplaceOut(False) if replace is not None: th.SetReplaceIn(True) th.SetInValue(replace) if replaceOut is not None: th.SetReplaceOut(True) th.SetOutValue(replaceOut) th.Update() out = th.GetOutput() out.GetPointData().Modified() # self._mapper = vtk.vtkSmartVolumeMapper() return Volume(out)
def _inputsort(obj): # def _inputsort_dolfin(obj): import dolfin u = None mesh = None if not utils.isSequence(obj): obj = [obj] for ob in obj: inputtype = str(type(ob)) # printc('inputtype is', inputtype, c=2) if "vedo" in inputtype: # skip vtk objects, will be added later continue if "dolfin" in inputtype or "ufl" in inputtype: if "MeshFunction" in inputtype: mesh = ob.mesh() if ob.dim() > 0: printc('MeshFunction of dim>0 not supported.', c='r') printc('Try e.g.: MeshFunction("size_t", mesh, 0)', c='r', italic=1) printc('instead of MeshFunction("size_t", mesh, 1)', c='r', strike=1) else: #printc(ob.dim(), mesh.num_cells(), len(mesh.coordinates()), len(ob.array())) V = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V) v2d = dolfin.vertex_to_dof_map(V) u.vector()[v2d] = ob.array() elif "Function" in inputtype or "Expression" in inputtype: u = ob elif "ufl.mathfunctions" in inputtype: # not working u = ob elif "Mesh" in inputtype: mesh = ob elif "algebra" in inputtype: mesh = ob.ufl_domain() #print('algebra', ob.ufl_domain()) if u and not mesh and hasattr(u, "function_space"): V = u.function_space() if V: mesh = V.mesh() if u and not mesh and hasattr(u, "mesh"): mesh = u.mesh() #printc('------------------------------------') #printc('mesh.topology dim=', mesh.topology().dim()) #printc('mesh.geometry dim=', mesh.geometry().dim()) #if u: printc('u.value_rank()', u.value_rank()) #if u and u.value_rank(): printc('u.value_dimension()', u.value_dimension(0)) # axis=0 ##if u: printc('u.value_shape()', u.value_shape()) return (mesh, u)
def tips(): from vedo import colors, __version__ msg = " ==========================================================\n" msg += "| Press: i print info about selected object |\n" msg += "| I print the RGB color under the mouse |\n" msg += "| <--> use arrows to reduce/increase opacity |\n" msg += "| w/s toggle wireframe/surface style |\n" msg += "| p/P change point size of vertices |\n" msg += "| l toggle edges visibility |\n" msg += "| x toggle mesh visibility |\n" msg += "| X invoke a cutter widget tool |\n" msg += "| 1-2 change mesh color |\n" msg += "| 3 change mesh texture |\n" msg += "| 4 use data array as colors, if present |\n" msg += "| 5-6 change background color(s) |\n" msg += "| 09+- (on keypad) or +/- to cycle axes style |\n" msg += "| k cycle available lighting styles |\n" msg += "| K cycle available shading styles |\n" msg += "| A toggle anti-aliasing |\n" msg += "| D toggle depth-peeling (for transparencies) |\n" msg += "| o/O add/remove light to scene and rotate it |\n" msg += "| n show surface mesh normals |\n" msg += "| a toggle interaction to Actor Mode |\n" msg += "| j toggle interaction to Joystick Mode |\n" msg += "| r reset camera position |\n" msg += "| C print current camera settings |\n" msg += "| S save a screenshot |\n" msg += "| E export rendering window to numpy file |\n" msg += "| q return control to python script |\n" msg += "| Esc abort execution and exit python kernel |\n" msg += "|----------------------------------------------------------|\n" msg += "| Mouse: Left-click rotate scene / pick actors |\n" msg += "| Middle-click pan scene |\n" msg += "| Right-click zoom scene in or out |\n" msg += "| Cntrl-click rotate scene |\n" msg += "|----------------------------------------------------------|\n" msg += "| Check out documentation at: https://vedo.embl.es |\n" msg += " ==========================================================" colors.printc(msg, dim=1) msg = " vedo " + __version__ + " " colors.printc(msg, invert=1, dim=1, end="") vtkVers = vtk.vtkVersion().GetVTKVersion() msg = "| vtk " + str(vtkVers) msg += " | python " + str(sys.version_info[0]) + "." + str( sys.version_info[1]) colors.printc(msg, invert=0, dim=1)