예제 #1
0
 def addCellScalars(self, scalars, name):
     """addCellScalars is OBSOLETE: use addCellArray."""
     colors.printc(
         "WARNING - addCellScalars is OBSOLETE: use addCellArray.",
         c='y',
         box='-')
     return self.addCellArray(scalars, name)
예제 #2
0
def pca(points, pvalue=.95, c='c', alpha=0.5, pcaAxes=False, legend=None):
    '''
    Show the oriented PCA ellipsoid that contains fraction pvalue of points.
        axes = True, show the 3 PCA semi axes
    Extra info is stored in actor.sphericity, actor.va, actor.vb, actor.vc
    (sphericity = 1 for a perfect sphere)
    '''
    try:
        from scipy.stats import f
    except:
        vc.printc("Error in ellipsoid(): scipy not installed. Skip.",1)
        return None
    if isinstance(points, vtk.vtkActor): points=vu.coordinates(points)
    if len(points) == 0: return None
    P = np.array(points, ndmin=2, dtype=float)
    cov = np.cov(P, rowvar=0)      # covariance matrix
    U, s, R = np.linalg.svd(cov)   # singular value decomposition
    p, n = s.size, P.shape[0]
    fppf = f.ppf(pvalue, p, n-p)*(n-1)*p*(n+1)/n/(n-p) # f % point function
    ua,ub,uc = np.sqrt(s*fppf)*2   # semi-axes (largest first)
    center = np.mean(P, axis=0)    # centroid of the hyperellipsoid
    sphericity = ( ((ua-ub)/(ua+ub))**2
                 + ((ua-uc)/(ua+uc))**2
                 + ((ub-uc)/(ub+uc))**2 )/3. *4.
    elliSource = vtk.vtkSphereSource()
    elliSource.SetThetaResolution(48)
    elliSource.SetPhiResolution(48)
    matri = vtk.vtkMatrix4x4()
    matri.DeepCopy((R[0][0] *ua, R[1][0] *ub, R[2][0] *uc, center[0],
                    R[0][1] *ua, R[1][1] *ub, R[2][1] *uc, center[1],
                    R[0][2] *ua, R[1][2] *ub, R[2][2] *uc, center[2], 0,0,0,1))
    vtra = vtk.vtkTransform()
    vtra.SetMatrix(matri)
    ftra = vtk.vtkTransformFilter()
    ftra.SetTransform(vtra)
    ftra.SetInputConnection(elliSource.GetOutputPort())
    ftra.Update()
    actor_elli = vu.makeActor(ftra.GetOutput(), c, alpha, legend=legend)
    actor_elli.GetProperty().BackfaceCullingOn()
    actor_elli.GetProperty().SetInterpolationToPhong()
    if pcaAxes:
        axs = []
        for ax in ([1,0,0], [0,1,0], [0,0,1]):
            l = vtk.vtkLineSource()
            l.SetPoint1([0,0,0])
            l.SetPoint2(ax)
            l.Update()
            t = vtk.vtkTransformFilter()
            t.SetTransform(vtra)
            vu.setInput(t, l.GetOutput())
            t.Update()
            axs.append(vu.makeActor(t.GetOutput(), c, alpha))
        finact = vu.makeAssembly([actor_elli]+axs, legend=legend)
    else : 
        finact = actor_elli
    setattr(finact, 'sphericity', sphericity)
    setattr(finact, 'va', ua)
    setattr(finact, 'vb', ub)
    setattr(finact, 'vc', uc)
    return finact
예제 #3
0
def _colorPoints(plist, cols, r, alpha, legend):
    n = len(plist)
    if n > len(cols):
        colors.printc("Mismatch in colorPoints()", n, len(cols), c=1)
        exit()
    if n != len(cols):
        colors.printc("Warning: mismatch in colorPoints()", n, len(cols))
    src = vtk.vtkPointSource()
    src.SetNumberOfPoints(n)
    src.Update()
    vertexFilter = vtk.vtkVertexGlyphFilter()
    vertexFilter.SetInputData(src.GetOutput())
    vertexFilter.Update()
    pd = vertexFilter.GetOutput()
    ucols = vtk.vtkUnsignedCharArray()
    ucols.SetNumberOfComponents(3)
    ucols.SetName("RGB")
    for i, p in enumerate(plist):
        c = np.array(colors.getColor(cols[i])) * 255
        ucols.InsertNextTuple3(c[0], c[1], c[2])
    pd.GetPoints().SetData(numpy_to_vtk(plist, deep=True))
    pd.GetPointData().SetScalars(ucols)
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputData(pd)
    mapper.ScalarVisibilityOn()
    actor = Actor()  #vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetInterpolationToFlat()
    actor.GetProperty().SetOpacity(alpha)
    actor.GetProperty().SetPointSize(r)
    return actor
def booleanOperation(actor1,
                     actor2,
                     operation='plus',
                     c=None,
                     alpha=1,
                     wire=False,
                     bc=None,
                     edges=False,
                     legend=None,
                     texture=None):
    '''Volumetric union, intersection and subtraction of surfaces'''
    try:
        bf = vtk.vtkBooleanOperationPolyDataFilter()
    except AttributeError:
        vc.printc('Boolean operation only possible for vtk version >= 8', 'r')
        return None
    poly1 = vu.polydata(actor1, True)
    poly2 = vu.polydata(actor2, True)
    if operation.lower() == 'plus':
        bf.SetOperationToUnion()
    elif operation.lower() == 'intersect':
        bf.SetOperationToIntersection()
    elif operation.lower() == 'minus':
        bf.SetOperationToDifference()
        bf.ReorientDifferenceCellsOn()
    if vu.vtkMV:
        bf.SetInputData(0, poly1)
        bf.SetInputData(1, poly2)
    else:
        bf.SetInputConnection(0, poly1.GetProducerPort())
        bf.SetInputConnection(1, poly2.GetProducerPort())
    bf.Update()
    actor = vu.makeActor(bf.GetOutput(), c, alpha, wire, bc, edges, legend,
                         texture)
    return actor
예제 #5
0
    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()
예제 #6
0
 def addPointVectors(self, vectors, name):
     """addPointVectors is OBSOLETE: use addPointArray."""
     colors.printc(
         "WARNING - addPointVectors is OBSOLETE: use addPointArray.",
         c='y',
         box='-')
     return self.addPointArray(vectors, name)
예제 #7
0
def procrustes(sources, rigid=False, legend=None):
    '''
    Return an Assembly of aligned source actors with
    the vtkProcrustesAlignmentFilter class. Assembly is normalized in space.
    
    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.
    '''
    group = vtk.vtkMultiBlockDataGroupFilter()
    for source in sources:
        if sources[0].N() != source.N():
            vc.printc('Procrustes error in align():' , c=1)
            vc.printc(' sources have different nr of points', c=1)
            exit(0)
        group.AddInputData(source.polydata())
    procrustes = vtk.vtkProcrustesAlignmentFilter()
    procrustes.StartFromCentroidOn()
    procrustes.SetInputConnection(group.GetOutputPort())
    if rigid:
        procrustes.GetLandmarkTransform().SetModeToRigidBody()
    procrustes.Update()
    
    acts = []
    for i in range(len(sources)):
        poly = procrustes.GetOutput().GetBlock(i)
        actor = Actor(poly)
        actor.SetProperty(sources[i].GetProperty())
        acts.append(actor)
    assem = Assembly(acts, legend=legend)
    assem.info['transform'] = procrustes.GetLandmarkTransform()
    return assem
예제 #8
0
def tips():
    from vtkplotter import colors
    msg =  "--------------------------------------------------------------\n"
    msg += "|Press: i     to print info about selected object            |\n"
    msg += "|       m     to minimise opacity of selected mesh           |\n"
    msg += "|       .,    to reduce/increase opacity                     |\n"
    msg += "|       /     to maximize opacity                            |\n"
    msg += "|       w/s   to toggle wireframe/solid style                |\n"
    msg += "|       p/P   to change point size of vertices               |\n"
    msg += "|       l/L   to change edge line width                      |\n"
    msg += "|       x     to toggle mesh visibility                      |\n"
    msg += "|       X     to pop up a cutter widget tool                 |\n"
    msg += "|       1-3   to change mesh color                           |\n"
    msg += "|       4     to change background color                     |\n"
    msg += "|       0-9   to change axes style (use keypad)              |\n"
    msg += "|       k/K   to show point/cell scalars as color            |\n"
    msg += "|       n     to show surface mesh normals                   |\n"
    msg += "|       a     to toggle interaction to Actor Mode            |\n"
    msg += "|       j     to toggle interaction to Joystick Mode         |\n"
    msg += "|       C     to print current camera info                   |\n"
    msg += "|       S     to save a screenshot                           |\n"
    msg += "|       q     to return control to python script             |\n"
    msg += "|       Esc   to close the rendering window                  |\n"
    msg += "|       F1    to abort execution and exit python             |\n"
    msg += "|------                                                      |\n"
    msg += "|Mouse: Left-click    to rotate scene / pick actors          |\n"
    msg += "|       Middle-click  to pan scene                           |\n"
    msg += "|       Right-click   to zoom scene in or out                |\n"
    msg += "|       Cntrl-click   to rotate scene perpendicularly        |\n"
    msg += "|------                                                      |\n"
    msg += "|Check out documentation at:  https://vtkplotter.embl.es     |\n"
    msg += "--------------------------------------------------------------\n"
    colors.printc(msg, dim=1)
예제 #9
0
def addButton(
    fnc,
    states=("On", "Off"),
    c=("w", "w"),
    bc=("dg", "dr"),
    pos=[20, 40],
    size=24,
    font="arial",
    bold=False,
    italic=False,
    alpha=1,
    angle=0,
):

    vp = settings.plotter_instance
    if not vp.renderer:
        colors.printc(
            "~timesError: Use addButton() after rendering the scene.", c=1)
        return
    bu = vtkio.Button(fnc, states, c, bc, pos, size, font, bold, italic, alpha,
                      angle)
    vp.renderer.AddActor2D(bu.actor)
    vp.window.Render()
    vp.buttons.append(bu)
    return bu
예제 #10
0
def loadImageData(filename, spacing=()):
    """Read and return a ``vtkImageData`` object from file.
    Use ``load`` instead.
    E.g. `img = load('myfile.tif').imagedata()`
    """
    if ".tif" in filename.lower():
        reader = vtk.vtkTIFFReader()
    elif ".slc" in filename.lower():
        reader = vtk.vtkSLCReader()
        if not reader.CanReadFile(filename):
            colors.printc("~prohibited Sorry bad slc file " + filename, c=1)
            return None
    elif ".vti" in filename.lower():
        reader = vtk.vtkXMLImageDataReader()
    elif ".mhd" in filename.lower():
        reader = vtk.vtkMetaImageReader()
    elif ".dem" in filename.lower():
        reader = vtk.vtkDEMReader()
    elif ".nii" in filename.lower():
        reader = vtk.vtkNIFTIImageReader()
    elif ".nrrd" in filename.lower():
        reader = vtk.vtkNrrdReader()
        if not reader.CanReadFile(filename):
            colors.printc("~prohibited Sorry bad nrrd file " + filename, c=1)
            return None
    reader.SetFileName(filename)
    reader.Update()
    image = reader.GetOutput()
    if len(spacing) == 3:
        image.SetSpacing(spacing[0], spacing[1], spacing[2])
    return image
예제 #11
0
def loadFile(filename, c, alpha, wire, bc, edges, legend, texture, smoothing,
             threshold, connectivity, scaling):
    '''Load a file of various formats.'''
    fl = filename.lower()
    if legend is True:
        legend = os.path.basename(filename)
    if fl.endswith('.xml') or fl.endswith(
            '.xml.gz'):  # Fenics tetrahedral file
        actor = loadDolfin(filename, c, alpha, wire, bc, edges, legend)
    elif fl.endswith('.neutral') or fl.endswith(
            '.neu'):  # neutral tetrahedral file
        actor = loadNeutral(filename, c, alpha, wire, bc, edges, legend)
    elif fl.endswith('.gmsh'):  # gmesh file
        actor = loadGmesh(filename, c, alpha, wire, bc, edges, legend)
    elif fl.endswith('.pcd'):  # PCL point-cloud format
        actor = loadPCD(filename, c, alpha, legend)
    elif fl.endswith('.3ds'):  # PCL point-cloud format
        actor = load3DS(filename, legend)
    elif fl.endswith('.tif') or fl.endswith('.slc'):  # tiff stack or slc
        img = loadImageData(filename)
        actor = vu.makeIsosurface(img, c, alpha, wire, bc, edges, legend,
                                  texture, smoothing, threshold, connectivity,
                                  scaling)
    elif fl.endswith('.png') or fl.endswith('.jpg') or fl.endswith('.jpeg'):
        actor = load2Dimage(filename, alpha)
    else:
        poly = loadPolyData(filename)
        if not poly:
            vc.printc('Unable to load', filename, c=1)
            return None
        actor = vu.makeActor(poly, c, alpha, wire, bc, edges, legend, texture)
        if fl.endswith('.txt') or fl.endswith('.xyz'):
            actor.GetProperty().SetPointSize(4)
    setattr(actor, 'filename', filename)
    return actor
예제 #12
0
 def print(self, txt='', counts=None):
     if counts:
         self._update(counts)
     else:
         self._update(self._counts + self.step)
     if self.bar != self._oldbar:
         self._oldbar = self.bar
         eraser = [' '] * self._lentxt + ['\b'] * self._lentxt
         eraser = ''.join(eraser)
         if self.ETA:
             vel = self._counts / (time.time() - self.clock0)
             remt = (self.stop - self._counts) / vel
             if remt > 60:
                 mins = int(remt / 60)
                 secs = remt - 60 * mins
                 mins = str(mins) + 'm'
                 secs = str(int(secs)) + 's '
             else:
                 mins = ''
                 secs = str(int(remt)) + 's '
             vel = str(round(vel, 1))
             eta = 'ETA: ' + mins + secs + '(' + vel + ' it/s) '
         else:
             eta = ''
         txt = eta + str(txt)
         s = self.bar + ' ' + eraser + txt + '\r'
         if self.color:
             vc.printc(s, c=self.color, end='')
         else:
             sys.stdout.write(s)
             sys.stdout.flush()
         if self.percent == 100:
             print('')
         self._lentxt = len(txt)
예제 #13
0
 def _colorPoints(plist, cols, r, alpha):
     n = len(plist)
     if n > len(cols):
         colors.printc("~times Error: mismatch in colorPoints()", n, len(cols), c=1)
         raise RuntimeError()
     if n != len(cols):
         colors.printc("~lightning Warning: mismatch in colorPoints()", n, len(cols))
     src = vtk.vtkPointSource()
     src.SetNumberOfPoints(n)
     src.Update()
     vgf = vtk.vtkVertexGlyphFilter()
     vgf.SetInputData(src.GetOutput())
     vgf.Update()
     pd = vgf.GetOutput()
     ucols = vtk.vtkUnsignedCharArray()
     ucols.SetNumberOfComponents(3)
     ucols.SetName("pointsRGB")
     for i in range(len(plist)):
         c = np.array(colors.getColor(cols[i])) * 255
         ucols.InsertNextTuple3(c[0], c[1], c[2])
     pd.GetPoints().SetData(numpy_to_vtk(plist, deep=True))
     pd.GetPointData().SetScalars(ucols)
     actor = Actor(pd, c, alpha)
     actor.mapper.ScalarVisibilityOn()
     actor.GetProperty().SetInterpolationToFlat()
     actor.GetProperty().SetPointSize(r)
     settings.collectable_actors.append(actor)
     return actor
예제 #14
0
파일: base.py 프로젝트: iPsych/vtkplotter
    def addCellScalars(self, scalars, name):
        """
        Add cell scalars and assign it a name.
        """
        data = self.inputdata()
        if isinstance(scalars, str):
            scalars = vtk_to_numpy(data.GetPointData().GetArray(scalars))

        if len(scalars) != data.GetNumberOfCells():
            colors.printc(
                "addCellScalars() Error: Number of scalars != nr. of cells",
                len(scalars),
                data.GetNumberOfCells(),
                c=1)
            raise RuntimeError()

        arr = numpy_to_vtk(np.ascontiguousarray(scalars), deep=True)
        arr.SetName(name)
        data.GetCellData().AddArray(arr)
        data.GetCellData().SetActiveScalars(name)
        if hasattr(self._mapper, 'SetArrayName'):
            self._mapper.SetArrayName(name)
        if settings.autoResetScalarRange:
            self._mapper.SetScalarRange(np.min(scalars), np.max(scalars))
        self._mapper.SetScalarModeToUseCellData()
        self._mapper.ScalarVisibilityOn()
        return self
예제 #15
0
파일: base.py 프로젝트: iPsych/vtkplotter
    def addPointScalars(self, scalars, name):
        """
        Add point scalars and assign it a name.

        |mesh_coloring| |mesh_coloring.py|_
        """
        data = self.inputdata()
        if len(scalars) != data.GetNumberOfPoints():
            colors.printc(
                '~times addPointScalars(): Number of scalars != nr. of points',
                len(scalars),
                data.GetNumberOfPoints(),
                c=1)
            raise RuntimeError()

        arr = numpy_to_vtk(np.ascontiguousarray(scalars), deep=True)
        arr.SetName(name)
        data.GetPointData().AddArray(arr)
        data.GetPointData().SetActiveScalars(name)
        if hasattr(self._mapper, 'SetArrayName'):
            self._mapper.SetArrayName(name)
        if settings.autoResetScalarRange:
            self._mapper.SetScalarRange(np.min(scalars), np.max(scalars))
        self._mapper.SetScalarModeToUsePointData()
        self._mapper.ScalarVisibilityOn()
        return self
예제 #16
0
    def lighting(self,
                 style='',
                 ambient=None,
                 diffuse=None,
                 specular=None,
                 specularPower=None,
                 specularColor=None,
                 enabled=True):
        """
        Set the ambient, diffuse, specular and specularPower lighting constants.

        :param str,int style: preset style, can be `[metallic, plastic, shiny, glossy, ambient]`
        :param float ambient: ambient fraction of emission [0-1]
        :param float diffuse: emission of diffused light in fraction [0-1]
        :param float specular: fraction of reflected light [0-1]
        :param float specularPower: precision of reflection [1-100]
        :param color specularColor: color that is being reflected by the surface
        :param bool enabled: enable/disable all surface light emission

        |wikiphong|

        |specular| |specular.py|_
        """
        pr = self.GetProperty()

        if style:
            if hasattr(pr, "GetColor"):  # could be Volume
                c = pr.GetColor()
            else:
                c = (1, 1, 0.99)
            mpr = self._mapper
            if hasattr(mpr,
                       'GetScalarVisibility') and mpr.GetScalarVisibility():
                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, (1, 1, 0.99)]
            elif style == 'ambient': pars = [1.0, 0.0, 0.0, 0, (1, 1, 1)]
            elif style == 'default': pars = [0.1, 1.0, 0.05, 5, c]
            else:
                colors.printc("Error in lighting(): Available styles are", c=1)
                colors.printc(
                    " [default, metallic, plastic, shiny, glossy, ambient]",
                    c=1)
                raise RuntimeError()
            pr.SetAmbient(pars[0])
            pr.SetDiffuse(pars[1])
            pr.SetSpecular(pars[2])
            pr.SetSpecularPower(pars[3])
            if hasattr(pr, "GetColor"): pr.SetSpecularColor(pars[4])

        if ambient is not None: pr.SetAmbient(ambient)
        if diffuse is not None: pr.SetDiffuse(diffuse)
        if specular is not None: pr.SetSpecular(specular)
        if specularPower is not None: pr.SetSpecularPower(specularPower)
        if specularColor is not None:
            pr.SetSpecularColor(colors.getColor(specularColor))
        if not enabled: pr.LightingOff()
        return self
예제 #17
0
def addIcon(iconActor, pos=3, size=0.08):

    vp = settings.plotter_instance
    if not vp.renderer:
        colors.printc(
            "~lightningWarning: Use addIcon() after first rendering the scene.",
            c=3)
        save_int = vp.interactive
        vp.show(interactive=0)
        vp.interactive = save_int
    widget = vtk.vtkOrientationMarkerWidget()
    widget.SetOrientationMarker(iconActor)
    widget.SetInteractor(vp.interactor)
    if utils.isSequence(pos):
        widget.SetViewport(pos[0] - size, pos[1] - size, pos[0] + size,
                           pos[1] + size)
    else:
        if pos < 2:
            widget.SetViewport(0, 1 - 2 * size, size * 2, 1)
        elif pos == 2:
            widget.SetViewport(1 - 2 * size, 1 - 2 * size, 1, 1)
        elif pos == 3:
            widget.SetViewport(0, 0, size * 2, size * 2)
        elif pos == 4:
            widget.SetViewport(1 - 2 * size, 0, 1, size * 2)
    widget.EnabledOn()
    widget.InteractiveOff()
    vp.widgets.append(widget)
    if iconActor in vp.actors:
        vp.actors.remove(iconActor)
    return widget
예제 #18
0
def screenshot(filename="screenshot.png"):
    """
    Save a screenshot of the current rendering window.
    """
    if not settings.plotter_instance or not settings.plotter_instance.window:
        colors.printc(
            '~bomb screenshot(): Rendering window is not present, skip.', c=1)
        return
    w2if = vtk.vtkWindowToImageFilter()
    w2if.SetInput(settings.plotter_instance.window)
    s = settings.screeshotScale
    w2if.SetScale(s, s)
    if settings.screenshotTransparentBackground:
        w2if.SetInputBufferTypeToRGBA()
    w2if.ReadFrontBufferOff()  # read from the back buffer
    w2if.Update()
    if filename.endswith('.png'):
        writer = vtk.vtkPNGWriter()
        writer.SetFileName(filename)
        writer.SetInputConnection(w2if.GetOutputPort())
        writer.Write()
    elif filename.endswith('.jpg'):
        writer = vtk.vtkJPEGWriter()
        writer.SetFileName(filename)
        writer.SetInputConnection(w2if.GetOutputPort())
        writer.Write()
    elif filename.endswith('.svg'):
        writer = vtk.vtkGL2PSExporter()
        #writer.SetFileFormatToPDF()
        #writer.SetFileFormatToTeX()
        writer.SetFileFormatToSVG()
        writer.CompressOff()
        writer.SetInput(settings.plotter_instance.window)
        writer.SetFilePrefix(filename.split('.')[0])
        writer.Write()
예제 #19
0
def _loadFile(filename, c, alpha, wire, bc, legend, texture, smoothing,
              threshold, connectivity):
    fl = filename.lower()
    if legend is True:
        legend = os.path.basename(filename)
    if fl.endswith('.xml') or fl.endswith(
            '.xml.gz'):  # Fenics tetrahedral file
        actor = loadDolfin(filename, c, alpha, wire, bc, legend)
    elif fl.endswith('.neutral') or fl.endswith(
            '.neu'):  # neutral tetrahedral file
        actor = loadNeutral(filename, c, alpha, wire, bc, legend)
    elif fl.endswith('.gmsh'):  # gmesh file
        actor = loadGmesh(filename, c, alpha, wire, bc, legend)
    elif fl.endswith('.pcd'):  # PCL point-cloud format
        actor = loadPCD(filename, c, alpha, legend)
    elif fl.endswith('.3ds'):  # PCL point-cloud format
        actor = load3DS(filename, legend)
    elif fl.endswith('.tif') or fl.endswith('.slc') or fl.endswith('.vti'):
        # tiff stack or slc or vti
        img = loadImageData(filename)
        actor = isosurface(img, c, alpha, wire, bc, legend, texture, smoothing,
                           threshold, connectivity)
    elif fl.endswith('.png') or fl.endswith('.jpg') or fl.endswith('.jpeg'):
        actor = load2Dimage(filename, alpha)
    else:
        poly = loadPolyData(filename)
        if not poly:
            colors.printc('Unable to load', filename, c=1)
            return None
        actor = Actor(poly, c, alpha, wire, bc, legend, texture)
        if fl.endswith('.txt') or fl.endswith('.xyz'):
            actor.GetProperty().SetPointSize(4)
    actor.filename = filename
    return actor
예제 #20
0
def booleanOperation(actor1, actor2, operation='plus', c=None, alpha=1,
                     wire=False, bc=None, legend=None, texture=None):
    '''Volumetric union, intersection and subtraction of surfaces.

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/boolean.py)        
    '''
    try:
        bf = vtk.vtkBooleanOperationPolyDataFilter()
    except AttributeError:
        vc.printc('Boolean operation only possible for vtk version >= 8', c='r')
        return None
    poly1 = actor1.polydata(True)
    poly2 = actor2.polydata(True)
    if operation.lower() == 'plus':
        bf.SetOperationToUnion()
    elif operation.lower() == 'intersect':
        bf.SetOperationToIntersection()
    elif operation.lower() == 'minus':
        bf.SetOperationToDifference()
        bf.ReorientDifferenceCellsOn()
    bf.SetInputData(0, poly1)
    bf.SetInputData(1, poly2)
    bf.Update()
    actor = Actor(bf.GetOutput(), c, alpha, wire, bc, legend, texture)
    return actor
예제 #21
0
 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=1)
         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
예제 #22
0
def linInterpolate(x, rangeX, rangeY):
    """
    Interpolate linearly variable x in rangeX onto rangeY.
    If x is a vector the linear weight is the distance to two the rangeX vectors.

    E.g. if x runs in rangeX=[x0,x1] and I want it to run in rangeY=[y0,y1] then
    y = linInterpolate(x, rangeX, rangeY) will interpolate x onto rangeY.

    |linInterpolate| |linInterpolate.py|_
    """
    if isSequence(x):
        x = np.array(x)
        x0, x1 = np.array(rangeX)
        y0, y1 = np.array(rangeY)
        if len(np.unique([x.shape, x0.shape, x1.shape, y1.shape])) > 1:
            colors.printc(
                "Error in linInterpolate(): mismatch in input shapes.", c=1)
            raise RuntimeError()
        dx = x1 - x0
        dxn = np.linalg.norm(dx)
        if not dxn:
            return y0
        s = np.linalg.norm(x - x0) / dxn
        t = np.linalg.norm(x - x1) / dxn
        st = s + t
        out = y0 * (t / st) + y1 * (s / st)
    else:  #faster
        x0 = rangeX[0]
        dx = rangeX[1] - x0
        if not dx:
            return rangeY[0]
        s = (x - x0) / dx
        out = rangeY[0] * (1 - s) + rangeY[1] * s
    return out
예제 #23
0
 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=1)
         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,
                                            returnIds=True)
                 if len(ids) <= acts[0].N():
                     self.events.append((tt, self.meshErode, acts, ids))
     else:
         self._performers[0].deletePoints(self._inputvalues)
     return self
예제 #24
0
def tips():
    from vtkplotter import colors
    msg = "|Press: i     to print info about selected object            |\n"
    msg += "|       m     to minimise opacity of selected mesh           |\n"
    msg += "|       .,    to reduce/increase opacity                     |\n"
    msg += "|       /     to maximize opacity                            |\n"
    msg += "|       w/s   to toggle wireframe/solid style                |\n"
    msg += "|       p/P   to change point size of vertices               |\n"
    msg += "|       l/L   to change edge line width                      |\n"
    msg += "|       x     to toggle mesh visibility                      |\n"
    msg += "|       X     to pop up a cutter widget tool                 |\n"
    msg += "|       1-3   to change mesh color                           |\n"
    msg += "|       4     to change background color                     |\n"
    msg += "|       k/K   to show point/cell scalars as color            |\n"
    msg += "|       n     to show surface mesh normals                   |\n"
    msg += "|       a     to toggle interaction to Actor Mode            |\n"
    msg += "|       j     to toggle interaction to Joystick Mode         |\n"
    msg += "|       C     to print current camera info                   |\n"
    msg += "|       S     to save a screenshot                           |\n"
    msg += "|       q/e   to continue/close the rendering window         |\n"
    msg += "|       Esc   to exit program                                |\n"
    msg += '|                                                            |\n'
    msg += "|Mouse: Left-click    to rotate scene / pick actors          |\n"
    msg += "|       Middle-click  to pan scene                           |\n"
    msg += "|       Right-click   to zoom scene in or out                |"
    colors.printc(msg, dim=1)
예제 #25
0
    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=1)
            raise RuntimeError()
        ff.Update()
        return self._update(ff.GetOutput())
def smoothMLS1D(actor, f=0.2, showNLines=0):
    '''
    Smooth actor or points with a Moving Least Squares variant.
    The list actor.variances contain the residue calculated for each point.
    Input actor's polydata is modified.
    
        f, smoothing factor - typical range s [0,2]
                      
        showNLines, build an actor showing the fitting line for N random points            
    '''
    coords = vu.coordinates(actor)
    ncoords = len(coords)
    Ncp = int(ncoords * f / 10)
    nshow = int(ncoords)
    if showNLines: ndiv = int(nshow / showNLines)

    if Ncp < 3:
        vc.printc('Please choose a higher fraction than ' + str(f), 1)
        Ncp = 3

    poly = vu.polydata(actor, True)
    vpts = poly.GetPoints()
    locator = vtk.vtkPointLocator()
    locator.SetDataSet(poly)
    locator.BuildLocator()
    vtklist = vtk.vtkIdList()
    variances, newline, acts = [], [], []
    for i, p in enumerate(coords):

        locator.FindClosestNPoints(Ncp, p, vtklist)
        points = []
        for j in range(vtklist.GetNumberOfIds()):
            trgp = [0, 0, 0]
            vpts.GetPoint(vtklist.GetId(j), trgp)
            points.append(trgp)
        if len(points) < 2: continue

        points = np.array(points)
        pointsmean = points.mean(axis=0)  # plane center
        uu, dd, vv = np.linalg.svd(points - pointsmean)
        newp = np.dot(p - pointsmean, vv[0]) * vv[0] + pointsmean
        variances.append(dd[1] + dd[2])
        newline.append(newp)

        if showNLines and not i % ndiv:
            fline = fitLine(points, lw=4, alpha=1)  # fitting plane
            iapts = vs.points(points)  # blue points
            acts += [fline, iapts]

    for i in range(ncoords):
        vpts.SetPoint(i, newline[i])

    if showNLines:
        apts = vs.points(newline, c='r 0.6', r=2)
        ass = vu.makeAssembly([apts] + acts)
        return ass  #NB: a demo actor is returned

    setattr(actor, 'variances', np.array(variances))
    return actor  #NB: original actor is modified
예제 #27
0
    def addPointArray(self, input_array, name):
        """
        Add point array and assign it a name.

        |mesh_coloring| |mesh_coloring.py|_
        """
        data = self.inputdata()

        if isinstance(input_array, vtk.vtkDataArray):
            data.GetPointData().AddArray(input_array)
            input_array.SetName(name)
            data.GetPointData().SetActiveScalars(name)
            self._mapper.ScalarVisibilityOn()
            self._mapper.SetScalarRange(input_array.GetRange())
            if hasattr(self._mapper, 'SetArrayName'):
                self._mapper.SetArrayName(name)
            self._mapper.SetScalarModeToUsePointData()
            return self

        if len(input_array) != data.GetNumberOfPoints():
            colors.printc(
                'Error in addPointArray(): Number of inputs != nr. of points',
                len(input_array),
                data.GetNumberOfPoints(),
                c=1)
            raise RuntimeError()

        nparr = np.ascontiguousarray(input_array)
        if len(nparr.shape) == 1:  # scalars
            varr = numpy_to_vtk(nparr, deep=True)
            varr.SetName(name)
            data.GetPointData().AddArray(varr)
            data.GetPointData().SetActiveScalars(name)
            self._mapper.SetScalarModeToUsePointData()
            if hasattr(self._mapper,
                       'ScalarVisibilityOn'):  # could be volume mapper
                self._mapper.ScalarVisibilityOn()
                self._mapper.SetScalarRange(varr.GetRange())

        elif len(nparr.shape) == 2:  # vectors or higher dim ntuples
            varr = vtk.vtkFloatArray()
            varr.SetNumberOfComponents(nparr.shape[1])
            varr.SetName(name)
            for v in nparr:
                varr.InsertNextTuple(v)
            data.GetPointData().AddArray(varr)
            if nparr.shape[1] == 3:
                data.GetPointData().SetActiveVectors(name)
        else:
            colors.printc('Error in addPointArray(): cannot deal with shape:',
                          nparr.shape,
                          c=1)
            return self

        if hasattr(self._mapper, 'SetArrayName'):
            self._mapper.SetArrayName(name)
        self._mapper.SetScalarModeToUsePointData()
        return self
예제 #28
0
def loadNeutral(filename, c, alpha, wire, bc, edges, legend):
    '''Reads a Neutral tetrahedral file format'''
    if not os.path.exists(filename):
        vc.printc(('Error in loadNeutral: Cannot find', filename), c=1)
        return None

    coords, connectivity = convertNeutral2Xml(filename)
    poly = buildPolyData(coords, connectivity, indexOffset=0)
    return vu.makeActor(poly, c, alpha, wire, bc, edges, legend)
예제 #29
0
def loadNeutral(filename, c='gold', alpha=1, wire=False, bc=None, legend=None):
    '''Reads a Neutral tetrahedral file format'''
    if not os.path.exists(filename):
        colors.printc('Error in loadNeutral: Cannot find', filename, c=1)
        return None

    coords, connectivity = convertNeutral2Xml(filename)
    poly = buildPolyData(coords, connectivity, indexOffset=0)
    return Actor(poly, c, alpha, wire, bc, legend)
예제 #30
0
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