Beispiel #1
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
def line(p0,
         p1=None,
         lw=1,
         tube=False,
         dotted=False,
         c='r',
         alpha=1.,
         legend=None):
    '''Build the line segment between points p0 and p1.
        
        if p0 is a list of points returns the line connecting them.
        
        if tube=True, lines are rendered as tubes of radius lw
    '''

    #detect if user is passing a list of points:
    if vu.isSequence(p0[0]):
        ppoints = vtk.vtkPoints()  # Generate the polyline
        poly = vtk.vtkPolyData()
        for i in range(len(p0)):
            p = p0[i]
            ppoints.InsertPoint(i, p[0], p[1], p[2])
        lines = vtk.vtkCellArray()  # Create the polyline.
        lines.InsertNextCell(len(p0))
        for i in range(len(p0)):
            lines.InsertCellPoint(i)
        poly.SetPoints(ppoints)
        poly.SetLines(lines)
    else:  # or just 2 points to link
        lineSource = vtk.vtkLineSource()
        lineSource.SetPoint1(p0)
        lineSource.SetPoint2(p1)
        lineSource.Update()
        poly = lineSource.GetOutput()

    if tube:
        tuf = vtk.vtkTubeFilter()
        tuf.SetNumberOfSides(12)
        #tuf.CappingOn()
        vu.setInput(tuf, poly)
        tuf.SetRadius(lw)
        tuf.Update()
        poly = tuf.GetOutput()
        actor = vu.makeActor(poly, c, alpha, legend=legend)
        actor.GetProperty().SetInterpolationToPhong()
    else:
        actor = vu.makeActor(poly, c, alpha, legend=legend)
        actor.GetProperty().SetLineWidth(lw)
        if dotted:
            actor.GetProperty().SetLineStipplePattern(0xf0f0)
            actor.GetProperty().SetLineStippleRepeatFactor(1)
    setattr(actor, 'base', np.array(p0))
    setattr(actor, 'top', np.array(p1))
    return actor
def cone(pos=[0, 0, 0],
         r=1,
         height=1,
         axis=[0, 0, 1],
         c='dg',
         alpha=1,
         legend=None,
         texture=None,
         res=48):
    '''
    Build a cone of specified radius r and height, centered at pos.
    '''
    con = vtk.vtkConeSource()
    con.SetResolution(res)
    con.SetRadius(r)
    con.SetHeight(height)
    con.SetDirection(axis)
    con.Update()
    actor = vu.makeActor(con.GetOutput(),
                         c,
                         alpha,
                         legend=legend,
                         texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(pos)
    v = vu.norm(axis) * height / 2
    setattr(actor, 'base', pos - v)
    setattr(actor, 'top', pos + v)
    return actor
Beispiel #4
0
def align(source, target, iters=100, rigid=False, legend=None):
    '''
    Return a copy of source actor which is aligned to
    target actor through vtkIterativeClosestPointTransform() method.
    The core of the algorithm is to match each vertex in one surface with
    the closest surface point on the other, then apply the transformation 
    that modify one surface to best match the other (in the least-square sense). 

    [**Example1**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/align1.py)
    [**Example2**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/align2.py)
    '''
    source = vu.polydata(source)
    target = vu.polydata(target)
    icp = vtk.vtkIterativeClosestPointTransform()
    icp.SetSource(source)
    icp.SetTarget(target)
    icp.SetMaximumNumberOfIterations(iters)
    if rigid:
        icp.GetLandmarkTransform().SetModeToRigidBody()
    icp.StartByMatchingCentroidsOn()
    icp.Update()
    icpTransformFilter = vtk.vtkTransformPolyDataFilter()
    vu.setInput(icpTransformFilter, source)
    icpTransformFilter.SetTransform(icp)
    icpTransformFilter.Update()
    poly = icpTransformFilter.GetOutput()
    actor = vu.makeActor(poly, legend=legend)
    if hasattr(source, 'GetProperty'):
        actor.SetProperty(source.GetProperty())
    setattr(actor, 'transform', icp.GetLandmarkTransform())
    return actor
Beispiel #5
0
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

    [**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 = 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
Beispiel #6
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
def lines(plist0,
          plist1=None,
          lw=1,
          dotted=False,
          c='r',
          alpha=1,
          legend=None):
    '''Build the line segments between two lists of points plist0 and plist1.
        plist0 can be also passed in the form [[point1, point2], ...]
    '''
    if plist1 is not None:
        plist0 = list(zip(plist0, plist1))

    polylns = vtk.vtkAppendPolyData()
    for twopts in plist0:
        lineSource = vtk.vtkLineSource()
        lineSource.SetPoint1(twopts[0])
        lineSource.SetPoint2(twopts[1])
        polylns.AddInputConnection(lineSource.GetOutputPort())
    polylns.Update()

    actor = vu.makeActor(polylns.GetOutput(), c, alpha, legend=legend)
    actor.GetProperty().SetLineWidth(lw)
    if dotted:
        actor.GetProperty().SetLineStipplePattern(0xf0f0)
        actor.GetProperty().SetLineStippleRepeatFactor(1)
    return actor
def points(plist, c='b', tags=[], r=5, alpha=1, legend=None):
    '''
    Build a vtkActor for a list of points.

    c can be a list of [R,G,B] colors of same length as plist
    
    If tags (a list of strings) is specified, is displayed along 
    with the points.
    '''

    if len(plist) == 0: return None
    if vu.isSequence(c) and vu.isSequence(c[0]):
        return _colorPoints(plist, c, r, alpha, legend)

    src = vtk.vtkPointSource()
    src.SetNumberOfPoints(len(plist))
    src.Update()
    pd = src.GetOutput()
    if len(plist) == 1:  #passing just one point
        pd.GetPoints().SetPoint(0, [0, 0, 0])
    else:
        for i, p in enumerate(plist):
            pd.GetPoints().SetPoint(i, p)
    actor = vu.makeActor(pd, c, alpha)
    actor.GetProperty().SetPointSize(r)
    if len(plist) == 1: actor.SetPosition(plist[0])

    if legend: setattr(actor, 'legend', legend)
    return actor
Beispiel #9
0
def loadFile(filename, c, alpha, wire, bc, edges, legend, texture, smoothing,
             threshold, connectivity, scaling):
    fl = filename.lower()
    if legend is True: legend = os.path.basename(filename)
    if '.xml' in fl or '.xml.gz' in fl:  # Fenics tetrahedral mesh file
        actor = loadXml(filename, c, alpha, wire, bc, edges, legend)
    elif '.neutral' in fl:  # neutral tetrahedral mesh file
        actor = loadNeutral(filename, c, alpha, wire, bc, edges, legend)
    elif '.gmsh' in fl:  # gmesh file
        actor = loadGmesh(filename, c, alpha, wire, bc, edges, legend)
    elif '.pcd' in fl:  # PCL point-cloud format
        actor = loadPCD(filename, c, alpha, legend)
    elif '.tif' in fl or '.slc' in fl:  # tiff stack or slc
        actor = loadVolume(filename, c, alpha, wire, bc, edges, legend,
                           texture, smoothing, threshold, connectivity,
                           scaling)
    elif '.png' in fl or '.jpg' in fl or '.jpeg' in fl:  # regular image
        actor = load2Dimage(filename, alpha)
    else:
        poly = loadPoly(filename)
        if not poly:
            vc.printc(('Unable to load', filename), c=1)
            return False
        actor = vu.makeActor(poly, c, alpha, wire, bc, edges, legend, texture)
        if '.txt' in fl or '.xyz' in fl:
            actor.GetProperty().SetPointSize(4)
    return actor
def recoSurface(points,
                bins=256,
                c='gold',
                alpha=1,
                wire=False,
                bc='t',
                edges=False,
                legend=None):
    '''
    Surface reconstruction from sparse points.
    '''

    if isinstance(points, vtk.vtkActor): points = vu.coordinates(points)
    N = len(points)
    if N < 50:
        print('recoSurface: Use at least 50 points.')
        return None
    points = np.array(points)

    ptsSource = vtk.vtkPointSource()
    ptsSource.SetNumberOfPoints(N)
    ptsSource.Update()
    vpts = ptsSource.GetOutput().GetPoints()
    for i, p in enumerate(points):
        vpts.SetPoint(i, p)
    polyData = ptsSource.GetOutput()

    distance = vtk.vtkSignedDistance()
    f = 0.1
    x0, x1, y0, y1, z0, z1 = polyData.GetBounds()
    distance.SetBounds(x0 - (x1 - x0) * f, x1 + (x1 - x0) * f,
                       y0 - (y1 - y0) * f, y1 + (y1 - y0) * f,
                       z0 - (z1 - z0) * f, z1 + (z1 - z0) * f)
    if polyData.GetPointData().GetNormals():
        distance.SetInputData(polyData)
        vu.setInput(distance, polyData)
    else:
        normals = vtk.vtkPCANormalEstimation()
        vu.setInput(normals, polyData)
        normals.SetSampleSize(int(N / 50))
        normals.SetNormalOrientationToGraphTraversal()
        distance.SetInputConnection(normals.GetOutputPort())
        print('Recalculating normals for', N, 'points, sample size=',
              int(N / 50))
    radius = vu.diagonalSize(polyData) / bins * 5
    distance.SetRadius(radius)
    distance.SetDimensions(bins, bins, bins)
    distance.Update()

    print('Calculating mesh from points with R =', radius)
    surface = vtk.vtkExtractSurface()
    surface.SetRadius(radius * .99)
    surface.HoleFillingOn()
    surface.ComputeNormalsOff()
    surface.ComputeGradientsOff()
    surface.SetInputConnection(distance.GetOutputPort())
    surface.Update()
    return vu.makeActor(surface.GetOutput(), c, alpha, wire, bc, edges, legend)
Beispiel #11
0
def loadRectilinearGrid(filename):  # not tested
    '''Load a vtkRectilinearGrid object from file and return a vtkActor.'''
    reader = vtk.vtkRectilinearGridReader()
    reader.SetFileName(filename)
    reader.Update()
    gf = vtk.vtkRectilinearGridGeometryFilter()
    gf.SetInputConnection(reader.GetOutputPort())
    gf.Update()
    return vu.makeActor(gf.GetOutput())
Beispiel #12
0
def spline(points, smooth=0.5, degree=2,
           s=2, c='b', alpha=1., nodes=False, legend=None, res=20):
    '''
    Return a vtkActor for a spline that doesnt necessarly pass exactly throught all points.

    Options:

        smooth, smoothing factor:
                0 = interpolate points exactly, 
                1 = average point positions

        degree = degree of the spline (1<degree<5)

        nodes = True shows also original the points 

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/tutorial.py)

    ![rspline](https://user-images.githubusercontent.com/32848391/35976041-15781de8-0cdf-11e8-997f-aeb725bc33cc.png)
    '''
    try:
        from scipy.interpolate import splprep, splev
    except ImportError:
        vc.printc(
            'Warning: ..scipy not installed, using vtkCardinalSpline instead.', c=5)
        return _vtkspline(points, s, c, alpha, nodes, legend, res)

    Nout = len(points)*res  # Number of points on the spline
    points = np.array(points)

    minx, miny, minz = np.min(points, axis=0)
    maxx, maxy, maxz = np.max(points, axis=0)
    maxb = max(maxx-minx, maxy-miny, maxz-minz)
    smooth *= maxb/2  # must be in absolute units

    x, y, z = points[:, 0], points[:, 1], points[:, 2]
    tckp, _ = splprep([x, y, z], task=0, s=smooth, k=degree)  # find the knots
    # evaluate spline, including interpolated points:
    xnew, ynew, znew = splev(np.linspace(0, 1, Nout), tckp)

    ppoints = vtk.vtkPoints()  # Generate the polyline for the spline
    profileData = vtk.vtkPolyData()
    for i in range(Nout):
        ppoints.InsertPoint(i, xnew[i], ynew[i], znew[i])
    lines = vtk.vtkCellArray()  # Create the polyline
    lines.InsertNextCell(Nout)
    for i in range(Nout):
        lines.InsertCellPoint(i)
    profileData.SetPoints(ppoints)
    profileData.SetLines(lines)
    actline = vu.makeActor(profileData, c=c, alpha=alpha, legend=legend)
    actline.GetProperty().SetLineWidth(s)
    if nodes:
        actnodes = vs.points(points, r=5, c=c, alpha=alpha)
        ass = vu.makeAssembly([actline, actnodes], legend=legend)
        return ass
    else:
        return actline
Beispiel #13
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)
def arrow(startPoint,
          endPoint,
          c,
          s=None,
          alpha=1,
          legend=None,
          texture=None,
          res=12,
          rwSize=None):
    '''Build a 3D arrow from startPoint to endPoint of section size s,
    expressed as the fraction of the window size.
    If s=None the arrow is scaled proportionally to its length.'''

    axis = np.array(endPoint) - np.array(startPoint)
    length = np.linalg.norm(axis)
    if not length: return None
    axis = axis / length
    theta = np.arccos(axis[2])
    phi = np.arctan2(axis[1], axis[0])
    arr = vtk.vtkArrowSource()
    arr.SetShaftResolution(res)
    arr.SetTipResolution(res)
    if s:
        sz = 0.02
        arr.SetTipRadius(sz)
        arr.SetShaftRadius(sz / 1.75)
        arr.SetTipLength(sz * 15)
    arr.Update()
    t = vtk.vtkTransform()
    t.RotateZ(phi * 57.3)
    t.RotateY(theta * 57.3)
    t.RotateY(-90)  #put it along Z
    if s:
        w, h = rwSize
        sz = (w + h) / 2 * s
        t.Scale(length, sz, sz)
    else:
        t.Scale(length, length, length)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, arr.GetOutput())
    tf.SetTransform(t)
    tf.Update()

    actor = vu.makeActor(tf.GetOutput(),
                         c,
                         alpha,
                         legend=legend,
                         texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(startPoint)
    actor.DragableOff()
    actor.PickableOff()
    setattr(actor, 'base', np.array(startPoint))
    setattr(actor, 'top', np.array(endPoint))
    return actor
def boundaries(actor, c='p', lw=5, legend=None):
    '''Build a copy of actor that shows the boundary lines of its surface.'''
    fe = vtk.vtkFeatureEdges()
    vu.setInput(fe, vu.polydata(actor))
    fe.BoundaryEdgesOn()
    fe.FeatureEdgesOn()
    fe.ManifoldEdgesOn()
    fe.NonManifoldEdgesOn()
    fe.ColoringOff()
    fe.Update()
    bactor = vu.makeActor(fe.GetOutput(), c=c, alpha=1, legend=legend)
    bactor.GetProperty().SetLineWidth(lw)
    return bactor
Beispiel #16
0
def loadStructuredPoints(filename):
    '''Load a vtkStructuredPoints object from file and return a vtkActor.

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/volumetric/readStructuredPoints.py)

    ![atomp2](https://user-images.githubusercontent.com/32848391/48198462-3b393700-e359-11e8-8272-670bd5f2db42.jpg)
    '''
    reader = vtk.vtkStructuredPointsReader()
    reader.SetFileName(filename)
    reader.Update()
    gf = vtk.vtkImageDataGeometryFilter()
    gf.SetInputConnection(reader.GetOutputPort())
    gf.Update()
    return vu.makeActor(gf.GetOutput())
def arrows(startPoints,
           endPoints=None,
           c='r',
           s=None,
           alpha=1,
           legend=None,
           res=8,
           rwSize=None):
    '''Build arrows between two lists of points startPoints and endPoints.
        startPoints can be also passed in the form [[point1, point2], ...]
    '''
    if endPoints is not None:
        startPoints = list(zip(startPoints, endPoints))

    polyapp = vtk.vtkAppendPolyData()
    for twopts in startPoints:
        startPoint, endPoint = twopts
        axis = np.array(endPoint) - np.array(startPoint)
        length = np.linalg.norm(axis)
        if not length: return None
        axis = axis / length
        theta = np.arccos(axis[2])
        phi = np.arctan2(axis[1], axis[0])
        arr = vtk.vtkArrowSource()
        arr.SetShaftResolution(res)
        arr.SetTipResolution(res)
        if s:
            sz = 0.02
            arr.SetTipRadius(sz)
            arr.SetShaftRadius(sz / 1.75)
            arr.SetTipLength(sz * 15)
        t = vtk.vtkTransform()
        t.Translate(startPoint)  ###
        t.RotateZ(phi * 57.3)
        t.RotateY(theta * 57.3)
        t.RotateY(-90)  #put it along Z
        if s:
            w, h = rwSize
            sz = (w + h) / 2 * s
            t.Scale(length, sz, sz)
        else:
            t.Scale(length, length, length)
        tf = vtk.vtkTransformPolyDataFilter()
        tf.SetInputConnection(arr.GetOutputPort())
        tf.SetTransform(t)
        polyapp.AddInputConnection(tf.GetOutputPort())

    polyapp.Update()
    actor = vu.makeActor(polyapp.GetOutput(), c, alpha, legend=legend)
    return actor
Beispiel #18
0
def delaunay2D(plist, tol=None, c='gold', alpha=0.5, wire=False, bc=None, edges=False, 
               legend=None, texture=None):
    '''
    Create a mesh from points in the XY plane.
    '''
    src = vtk.vtkPointSource()
    src.SetNumberOfPoints(len(plist))
    src.Update()
    pd = src.GetOutput()
    for i,p in enumerate(plist): pd.GetPoints().SetPoint(i, p)
    delny = vtk.vtkDelaunay2D()
    vu.setInput(delny, pd)
    if tol: delny.SetTolerance(tol)
    delny.Update()
    return vu.makeActor(delny.GetOutput(), c, alpha, wire, bc, edges, legend, texture)
Beispiel #19
0
def boundaries(actor, c='p', lw=5, legend=None):
    '''Build a copy of actor that shows the boundary lines of its surface.

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/tutorial.py)    
    '''
    fe = vtk.vtkFeatureEdges()
    vu.setInput(fe, vu.polydata(actor))
    fe.BoundaryEdgesOn()
    fe.FeatureEdgesOn()
    fe.ManifoldEdgesOn()
    fe.NonManifoldEdgesOn()
    fe.ColoringOff()
    fe.Update()
    bactor = vu.makeActor(fe.GetOutput(), c=c, alpha=1, legend=legend)
    bactor.GetProperty().SetLineWidth(lw)
    return bactor
Beispiel #20
0
def surfaceIntersection(actor1, actor2, tol=1e-06, lw=3,
                        c=None, alpha=1, legend=None):
    '''Intersect 2 surfaces and return a line actor'''
    try:
        bf = vtk.vtkIntersectionPolyDataFilter()
    except AttributeError:
        vc.printc('surfaceIntersection only possible for vtk version > 6','r')
        return None
    poly1 = vu.polydata(actor1, True)
    poly2 = vu.polydata(actor2, True)
    bf.SetInputData(0, poly1)
    bf.SetInputData(1, poly2)
    bf.Update()
    if c is None: c = actor1.GetProperty().GetColor()
    actor = vu.makeActor(bf.GetOutput(), c, alpha, 0, legend=legend)
    actor.GetProperty().SetLineWidth(lw)
    return actor
def hyperboloid(pos=[0, 0, 0],
                a2=1,
                value=0.5,
                height=1,
                axis=[0, 0, 1],
                c='magenta',
                alpha=1,
                legend=None,
                texture=None,
                res=50):
    '''
    Build a hyperboloid of specified aperture a2 and height, centered at pos.
    '''
    q = vtk.vtkQuadric()
    q.SetCoefficients(2, 2, -1 / a2, 0, 0, 0, 0, 0, 0, 0)
    #F(x,y,z) = a0*x^2 + a1*y^2 + a2*z^2
    #         + a3*x*y + a4*y*z + a5*x*z
    #         + a6*x   + a7*y   + a8*z  +a9
    sample = vtk.vtkSampleFunction()
    sample.SetSampleDimensions(res, res, res)
    sample.SetImplicitFunction(q)

    contours = vtk.vtkContourFilter()
    contours.SetInputConnection(sample.GetOutputPort())
    contours.GenerateValues(1, value, value)
    contours.Update()

    axis = np.array(axis) / np.linalg.norm(axis)
    theta = np.arccos(axis[2])
    phi = np.arctan2(axis[1], axis[0])
    t = vtk.vtkTransform()
    t.PostMultiply()
    t.RotateY(theta * 57.3)
    t.RotateZ(phi * 57.3)
    t.Scale(1, 1, height)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, contours.GetOutput())
    tf.SetTransform(t)
    tf.Update()
    pd = tf.GetOutput()

    actor = vu.makeActor(pd, c=c, alpha=alpha, legend=legend, texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.GetMapper().ScalarVisibilityOff()
    actor.SetPosition(pos)
    return actor
def ring(pos=[0, 0, 0],
         r=1,
         thickness=0.1,
         axis=[0, 0, 1],
         c='khaki',
         alpha=1,
         wire=False,
         legend=None,
         texture=None,
         res=30):
    '''
    Build a torus of specified outer radius r internal radius thickness, centered at pos.
    '''
    rs = vtk.vtkParametricTorus()
    rs.SetRingRadius(r)
    rs.SetCrossSectionRadius(thickness)
    pfs = vtk.vtkParametricFunctionSource()
    pfs.SetParametricFunction(rs)
    pfs.SetUResolution(res * 3)
    pfs.SetVResolution(res)
    pfs.Update()

    nax = np.linalg.norm(axis)
    if nax: axis = np.array(axis) / nax
    theta = np.arccos(axis[2])
    phi = np.arctan2(axis[1], axis[0])
    t = vtk.vtkTransform()
    t.PostMultiply()
    t.RotateY(theta * 57.3)
    t.RotateZ(phi * 57.3)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, pfs.GetOutput())
    tf.SetTransform(t)
    tf.Update()
    pd = tf.GetOutput()

    actor = vu.makeActor(pd,
                         c=c,
                         alpha=alpha,
                         wire=wire,
                         legend=legend,
                         texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(pos)
    return actor
def helix(startPoint=[0, 0, 0],
          endPoint=[1, 1, 1],
          coils=20,
          r=None,
          thickness=None,
          c='grey',
          alpha=1,
          legend=None,
          texture=None):
    '''
    Build a spring actor of specified nr of coils between startPoint and endPoint
    '''
    diff = endPoint - np.array(startPoint)
    length = np.linalg.norm(diff)
    if not length: return None
    if not r: r = length / 20
    trange = np.linspace(0, length, num=50 * coils)
    om = 6.283 * (coils - .5) / length
    pts = [[r * np.cos(om * t), r * np.sin(om * t), t] for t in trange]
    pts = [[0, 0, 0]] + pts + [[0, 0, length]]
    diff = diff / length
    theta = np.arccos(diff[2])
    phi = np.arctan2(diff[1], diff[0])
    sp = vu.polydata(line(pts), False)
    t = vtk.vtkTransform()
    t.RotateZ(phi * 57.3)
    t.RotateY(theta * 57.3)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, sp)
    tf.SetTransform(t)
    tf.Update()
    tuf = vtk.vtkTubeFilter()
    tuf.SetNumberOfSides(12)
    tuf.CappingOn()
    vu.setInput(tuf, tf.GetOutput())
    if not thickness: thickness = r / 10
    tuf.SetRadius(thickness)
    tuf.Update()
    poly = tuf.GetOutput()
    actor = vu.makeActor(poly, c, alpha, legend=legend, texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(startPoint)
    setattr(actor, 'base', np.array(startPoint))
    setattr(actor, 'top', np.array(endPoint))
    return actor
Beispiel #24
0
def _vtkspline(points, s, c, alpha, nodes, legend, res):
    numberOfOutputPoints = len(points)*res  # Number of points on the spline
    numberOfInputPoints = len(points)  # One spline for each direction.
    aSplineX = vtk.vtkCardinalSpline()  # interpolate the x values
    aSplineY = vtk.vtkCardinalSpline()  # interpolate the y values
    aSplineZ = vtk.vtkCardinalSpline()  # interpolate the z values

    inputPoints = vtk.vtkPoints()
    for i in range(0, numberOfInputPoints):
        x = points[i][0]
        y = points[i][1]
        z = points[i][2]
        aSplineX.AddPoint(i, x)
        aSplineY.AddPoint(i, y)
        aSplineZ.AddPoint(i, z)
        inputPoints.InsertPoint(i, x, y, z)

    inputData = vtk.vtkPolyData()
    inputData.SetPoints(inputPoints)
    points = vtk.vtkPoints()
    profileData = vtk.vtkPolyData()
    for i in range(0, numberOfOutputPoints):
        t = (numberOfInputPoints-1.)/(numberOfOutputPoints-1.)*i
        x, y, z = aSplineX.Evaluate(
            t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t)
        points.InsertPoint(i, x, y, z)

    lines = vtk.vtkCellArray()  # Create the polyline.
    lines.InsertNextCell(numberOfOutputPoints)
    for i in range(0, numberOfOutputPoints):
        lines.InsertCellPoint(i)

    profileData.SetPoints(points)
    profileData.SetLines(lines)
    actline = vu.makeActor(profileData, c=c, alpha=alpha, legend=legend)
    actline.GetProperty().SetLineWidth(s)
    actline.GetProperty().SetInterpolationToPhong()
    if nodes:
        pts = vu.coordinates(inputData)
        actnodes = vs.points(pts, r=s*1.5, c=c, alpha=alpha)
        ass = vu.makeAssembly([actline, actnodes], legend=legend)
        return ass
    else:
        return actline
def ellipsoid(pos=[0, 0, 0],
              axis1=[1, 0, 0],
              axis2=[0, 2, 0],
              axis3=[0, 0, 3],
              c='c',
              alpha=1,
              legend=None,
              texture=None,
              res=24):
    """
    Build a 3D ellipsoid centered at position pos.
    Axis1 and axis2 are only used to define sizes and one azimuth angle
    """
    elliSource = vtk.vtkSphereSource()
    elliSource.SetThetaResolution(res)
    elliSource.SetPhiResolution(res)
    elliSource.Update()
    l1 = np.linalg.norm(axis1)
    l2 = np.linalg.norm(axis2)
    l3 = np.linalg.norm(axis3)
    axis1 = np.array(axis1) / l1
    axis2 = np.array(axis2) / l2
    axis3 = np.array(axis3) / l3
    angle = np.arcsin(np.dot(axis1, axis2))
    theta = np.arccos(axis3[2])
    phi = np.arctan2(axis3[1], axis3[0])

    t = vtk.vtkTransform()
    t.PostMultiply()
    t.Scale(l1, l2, l3)
    t.RotateX(angle * 57.3)
    t.RotateY(theta * 57.3)
    t.RotateZ(phi * 57.3)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, elliSource.GetOutput())
    tf.SetTransform(t)
    tf.Update()
    pd = tf.GetOutput()

    actor = vu.makeActor(pd, c=c, alpha=alpha, legend=legend, texture=texture)
    actor.GetProperty().BackfaceCullingOn()
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(pos)
    return actor
def sphere(pos=[0, 0, 0],
           r=1,
           c='r',
           alpha=1,
           wire=False,
           legend=None,
           texture=None,
           res=24):
    '''Build a sphere at position pos of radius r.'''
    ss = vtk.vtkSphereSource()
    ss.SetRadius(r)
    ss.SetThetaResolution(res)
    ss.SetPhiResolution(res)
    ss.Update()
    pd = ss.GetOutput()
    actor = vu.makeActor(pd, c, alpha, wire, legend=legend, texture=texture)
    actor.GetProperty().SetInterpolationToPhong()
    actor.SetPosition(pos)
    return actor
Beispiel #27
0
def extractLargestRegion(actor, legend=None):
    '''Keep only the largest connected part of a mesh and discard all the smaller pieces.

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/largestregion.py)
    '''
    conn = vtk.vtkConnectivityFilter()
    conn.SetExtractionModeToLargestRegion()
    conn.ScalarConnectivityOff()
    poly = vu.polydata(actor, True)
    vu.setInput(conn, poly)
    conn.Update()
    epoly = conn.GetOutput()
    if legend is True and hasattr(actor, 'legend'):
        legend = actor.legend
    eact = vu.makeActor(epoly, legend)
    pr = vtk.vtkProperty()
    pr.DeepCopy(actor.GetProperty())
    eact.SetProperty(pr)
    return eact
Beispiel #28
0
def delaunay2D(plist, tol=None, c='gold', alpha=0.5, wire=False, bc=None, edges=False,
               legend=None, texture=None):
    '''
    Create a mesh from points in the XY plane.

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/basic/delaunay2d.py)
    '''
    src = vtk.vtkPointSource()
    src.SetNumberOfPoints(len(plist))
    src.Update()
    pd = src.GetOutput()
    for i, p in enumerate(plist):
        pd.GetPoints().SetPoint(i, p)
    delny = vtk.vtkDelaunay2D()
    vu.setInput(delny, pd)
    if tol:
        delny.SetTolerance(tol)
    delny.Update()
    return vu.makeActor(delny.GetOutput(), c, alpha, wire, bc, edges, legend, texture)
def plane(pos=[0, 0, 0],
          normal=[0, 0, 1],
          sx=1,
          sy=None,
          c='g',
          bc='darkgreen',
          alpha=1,
          legend=None,
          texture=None):
    '''
    Draw a plane of size sx and sy oriented perpendicular to vector normal  
    and so that it passes through point pos.
    '''
    if sy is None: sy = sx
    ps = vtk.vtkPlaneSource()
    ps.SetResolution(1, 1)
    tri = vtk.vtkTriangleFilter()
    tri.SetInputConnection(ps.GetOutputPort())
    tri.Update()
    poly = tri.GetOutput()
    axis = np.array(normal) / np.linalg.norm(normal)
    theta = np.arccos(axis[2])
    phi = np.arctan2(axis[1], axis[0])
    t = vtk.vtkTransform()
    t.PostMultiply()
    t.Scale(sx, sy, 1)
    t.RotateY(theta * 57.3)
    t.RotateZ(phi * 57.3)
    tf = vtk.vtkTransformPolyDataFilter()
    vu.setInput(tf, poly)
    tf.SetTransform(t)
    tf.Update()
    pd = tf.GetOutput()
    actor = vu.makeActor(pd,
                         c=c,
                         bc=bc,
                         alpha=alpha,
                         legend=legend,
                         texture=texture)
    actor.SetPosition(pos)
    actor.PickableOff()
    return actor
Beispiel #30
0
def probePlane(img, origin=(0, 0, 0), normal=(1, 0, 0)):
    '''
    Takes a vtkImageData and probes its scalars on a plane. 

    [**Example**](https://github.com/marcomusy/vtkplotter/blob/master/examples/volumetric/probePlane.py)

    (https://user-images.githubusercontent.com/32848391/48198461-3aa0a080-e359-11e8-8c29-18f287f105e6.jpg)
    '''
    plane = vtk.vtkPlane()
    plane.SetOrigin(origin)
    plane.SetNormal(normal)

    planeCut = vtk.vtkCutter()
    planeCut.SetInputData(img)
    planeCut.SetCutFunction(plane)
    planeCut.Update()
    cutActor = vu.makeActor(planeCut.GetOutput(), c=None)  # ScalarVisibilityOn
    cutMapper = cutActor.GetMapper()
    cutMapper.SetScalarRange(img.GetPointData().GetScalars().GetRange())
    return cutActor