예제 #1
0
 def __init__(self, verts, faces, filling_factors):
     mesh = Mesh([verts, faces])
     self.filling_factors = filling_factors
     self.verts = verts
     self.faces = faces
     self.all_cells = mesh.faces()
     self.n_cells = mesh.NCells()
예제 #2
0
파일: volume.py 프로젝트: yyeboah/vedo
    def slicePlane(self, origin=(0,0,0), normal=(1,1,1)):
        """Extract the slice along a given plane position and normal.

        |slicePlane| |slicePlane.py|_
        """
        reslice = vtk.vtkImageReslice()
        reslice.SetInputData(self._data)
        reslice.SetOutputDimensionality(2)
        newaxis = utils.versor(normal)
        pos = np.array(origin)
        initaxis = (0,0,1)
        crossvec = np.cross(initaxis, newaxis)
        angle = np.arccos(np.dot(initaxis, newaxis))
        T = vtk.vtkTransform()
        T.PostMultiply()
        T.RotateWXYZ(np.rad2deg(angle), crossvec)
        T.Translate(pos)
        M = T.GetMatrix()
        reslice.SetResliceAxes(M)
        reslice.SetInterpolationModeToLinear()
        reslice.Update()
        vslice = vtk.vtkImageDataGeometryFilter()
        vslice.SetInputData(reslice.GetOutput())
        vslice.Update()
        msh = Mesh(vslice.GetOutput())
        msh.SetOrientation(T.GetOrientation())
        msh.SetPosition(pos)
        return msh
예제 #3
0
def show_vedo_mesh_old(verts, faces, filling_factors):
    start = time.time()

    mesh = Mesh([verts, faces])

    mesh.backColor('blue').lineColor('white').lineWidth(0)

    # retrieve them as numpy arrays
    # printc('points():\n', mesh.points(), c=3)
    # printc('faces(): \n', mesh.faces(), c=3)

    # show(mesh, labs, __doc__, viewup='z', axes=1)

    colors = []
    all_cells = mesh.faces()
    for i in range(mesh.NCells()):
        points = all_cells[i]
        ff_sum = 0
        for p in points:
            ff_sum += filling_factors[p]

        c = int((ff_sum / 3) * 200)
        colors.append((c, 0, 0))

    mesh.cellIndividualColors(colors)
    # show(mesh, __doc__, viewup='z', interactive=False, camera={'pos': (-1, -1, 2)})  # isometric: 2 2 2
    plotter = Plotter(size=(1024, 1024), interactive=False)
    plotter += mesh
    plotter += __doc__
    plotter.show(viewup='z', camera={'pos': (-1, -1, 2)})

    screenshot()
    end = time.time()
    print(f"Calculation took {end - start} seconds.")
예제 #4
0
    def isosurface(self, threshold=True):
        """Return a ``Mesh`` isosurface.

        :param float,list threshold: value or list of values to draw the isosurface(s)
        """
        if not self._data.GetPointData().GetScalars():
            self.mapCellsToPoints()
        scrange = self._data.GetPointData().GetScalars().GetRange()
        cf = vtk.vtkContourFilter()  #vtk.vtkContourGrid()
        cf.SetInputData(self._data)

        if utils.isSequence(threshold):
            cf.SetNumberOfContours(len(threshold))
            for i, t in enumerate(threshold):
                cf.SetValue(i, t)
            cf.Update()
        else:
            if threshold is True:
                threshold = (2 * scrange[0] + scrange[1]) / 3.0
                #print('automatic threshold set to ' + utils.precision(threshold, 3), end=' ')
                #print('in [' + utils.precision(scrange[0], 3) + ', ' + utils.precision(scrange[1], 3)+']')
            cf.SetValue(0, threshold)
            cf.Update()

        clp = vtk.vtkCleanPolyData()
        clp.SetInputData(cf.GetOutput())
        clp.Update()
        msh = Mesh(clp.GetOutput(), c=None).phong()
        msh._mapper.SetLookupTable(utils.ctf2lut(self))
        return msh
예제 #5
0
파일: assembly.py 프로젝트: zymale/vedo
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
예제 #6
0
 def zSlice(self, k):
     """Extract the slice at index `i` of volume along z-axis."""
     vslice = vtk.vtkImageDataGeometryFilter()
     vslice.SetInputData(self.imagedata())
     nx, ny, nz = self.imagedata().GetDimensions()
     if k > nz - 1:
         k = nz - 1
     vslice.SetExtent(0, nx, 0, ny, k, k)
     vslice.Update()
     return Mesh(vslice.GetOutput())
예제 #7
0
 def ySlice(self, j):
     """Extract the slice at index `j` of volume along y-axis."""
     vslice = vtk.vtkImageDataGeometryFilter()
     vslice.SetInputData(self.imagedata())
     nx, ny, nz = self.imagedata().GetDimensions()
     if j > ny - 1:
         j = ny - 1
     vslice.SetExtent(0, nx, j, j, 0, nz)
     vslice.Update()
     return Mesh(vslice.GetOutput())
예제 #8
0
 def xSlice(self, i):
     """Extract the slice at index `i` of volume along x-axis."""
     vslice = vtk.vtkImageDataGeometryFilter()
     vslice.SetInputData(self.imagedata())
     nx, ny, nz = self.imagedata().GetDimensions()
     if i > nx - 1:
         i = nx - 1
     vslice.SetExtent(i, i, 0, ny, 0, nz)
     vslice.Update()
     return Mesh(vslice.GetOutput())
예제 #9
0
    def toPoints(self):
        """Extract all image voxels as points.
        This function takes an input ``Volume`` and creates an ``Mesh``
        that contains the points and the point attributes.

        See example script: |vol2points.py|_
        """
        v2p = vtk.vtkImageToPoints()
        v2p.SetInputData(self.imagedata())
        v2p.Update()
        mpts = Mesh(v2p.GetOutput())
        return mpts
예제 #10
0
    def __init__(self, *inputobj, **options):

        c = options.pop("c", None)
        alpha = options.pop("alpha", 1)
        exterior = options.pop("exterior", False)
        fast = options.pop("fast", False)
        computeNormals = options.pop("computeNormals", False)

        mesh, u = _inputsort(inputobj)
        if not mesh:
            return

        if exterior:
            import dolfin
            meshc = dolfin.BoundaryMesh(mesh, 'exterior')
        else:
            meshc = mesh

        if hasattr(mesh, "coordinates"):
            coords = mesh.coordinates()
        else:
            coords = mesh.geometry.points

        poly = utils.buildPolyData(coords,
                                   meshc.cells(),
                                   fast=fast,
                                   tetras=True)

        Mesh.__init__(
            self,
            poly,
            c=c,
            alpha=alpha,
            computeNormals=computeNormals,
        )

        self.mesh = mesh  # holds a dolfin Mesh obj
        self.u = u  # holds a dolfin function_data
        # holds the actual values of u on the mesh
        self.u_values = _compute_uvalues(u, mesh)
예제 #11
0
    def slice(self, origin=(0, 0, 0), normal=(1, 0, 0)):
        """Return a 2D slice of the mesh by a plane passing through origin and
        assigned normal."""
        strn = str(normal)
        if strn == "x": normal = (1, 0, 0)
        elif strn == "y": normal = (0, 1, 0)
        elif strn == "z": normal = (0, 0, 1)
        elif strn == "-x": normal = (-1, 0, 0)
        elif strn == "-y": normal = (0, -1, 0)
        elif strn == "-z": normal = (0, 0, -1)
        plane = vtk.vtkPlane()
        plane.SetOrigin(origin)
        plane.SetNormal(normal)

        cc = vtk.vtkCutter()
        cc.SetInputData(self._data)
        cc.SetCutFunction(plane)
        cc.Update()
        msh = Mesh(cc.GetOutput()).flat().lighting('ambient')
        msh._mapper.SetLookupTable(utils.ctf2lut(self))
        return msh
예제 #12
0
파일: picture.py 프로젝트: prithishh3/vedo
    def polygonize(self, threshold=None, flip=False):
        """
        Create a polygonal Mesh from a Picture by filling regions with pixels
        luminosity above a specified threshold.

        Parameters
        ----------
        threshold : float, optional
            The default is None, e.i. 1/3 of the scalar range.

        Returns
        -------
        Mesh
            A polygonal mesh.
        """
        from vedo.mesh import Mesh
        mgf = vtk.vtkImageMagnitude()
        mgf.SetInputData(self._data)
        mgf.Update()
        msq = vtk.vtkMarchingSquares()
        msq.SetInputData(mgf.GetOutput())
        if threshold is None:
            r0, r1 = self._data.GetScalarRange()
            threshold = r0 + (r1 - r0) / 3
        msq.SetValue(0, threshold)
        msq.Update()
        if flip:
            rs = vtk.vtkReverseSense()
            rs.SetInputData(msq.GetOutput())
            rs.ReverseCellsOn()
            rs.ReverseNormalsOff()
            rs.Update()
            output = rs.GetOutput()
        else:
            output = msq.GetOutput()
        ctr = vtk.vtkContourTriangulator()
        ctr.SetInputData(output)
        ctr.Update()
        return Mesh(ctr.GetOutput(), c='k').bc('t').lighting('off')
예제 #13
0
    def show_vedo_mesh(self):
        start = time.time()

        # retrieve them as numpy arrays
        # printc('points():\n', mesh.points(), c=3)
        # printc('faces(): \n', mesh.faces(), c=3)

        # show(mesh, labs, __doc__, viewup='z', axes=1)

        with Pool(processes=8) as pool:
            colors = pool.map(self.calc_color, range(self.n_cells))

        mesh = Mesh([self.verts, self.faces])
        mesh.backColor('blue').lineColor('white').lineWidth(0)
        mesh.cellIndividualColors(colors)
        show(mesh,
             __doc__,
             viewup='z',
             interactive=False,
             camera={'pos': (-1, -1, 2)})  # isometric: 2 2 2
        screenshot()
        end = time.time()
        print(f"Calculation took {end - start} seconds.")
예제 #14
0
파일: cli.py 프로젝트: marcomusy/vedo
def draw_scene(args):

    nfiles = len(args.files)
    if nfiles == 0:
        printc("No input files.", c='r')
        return
    humansort(args.files)

    wsize = "auto"
    if args.full_screen:
        wsize = "full"

    if args.ray_cast_mode:
        if args.background == "":
            args.background = "bb"

    if args.background == "":
        args.background = "white"

    if args.background_grad:
        args.background_grad = getColor(args.background_grad)

    if nfiles == 1 and args.files[0].endswith(".gif"):  ###can be improved
        frames = load(args.files[0])
        applications.Browser(frames).show(bg=args.background,
                                          bg2=args.background_grad)
        return  ##########################################################

    if args.scrolling_mode:
        args.multirenderer_mode = False

    N = None
    if args.multirenderer_mode:
        if nfiles < 201:
            N = nfiles
        if nfiles > 200:
            printc("Warning: option '-n' allows a maximum of 200 files", c=1)
            printc("         you are trying to load ",
                   nfiles,
                   " files.\n",
                   c=1)
            N = 200
        vp = Plotter(size=wsize,
                     N=N,
                     bg=args.background,
                     bg2=args.background_grad)
        settings.immediateRendering = False
        vp.axes = args.axes_type
        for i in range(N):
            vp.addHoverLegend(at=i)
        if args.axes_type == 4 or args.axes_type == 5:
            vp.axes = 0
    else:
        N = nfiles
        vp = Plotter(size=wsize, bg=args.background, bg2=args.background_grad)
        vp.axes = args.axes_type
        vp.addHoverLegend()

    vp.sharecam = not args.no_camera_share

    wire = False
    if args.wireframe:
        wire = True

    ##########################################################
    # special case of SLC/TIFF volumes with -g option
    if args.ray_cast_mode:
        # print('DEBUG special case of SLC/TIFF volumes with -g option')

        vol = io.load(args.files[0], force=args.reload)

        if not isinstance(vol, Volume):
            printc("Type Error: expected a Volume but loaded",
                   type(vol),
                   'object.',
                   c=1)
            return

        sp = vol.spacing()
        vol.spacing([
            sp[0] * args.x_spacing, sp[1] * args.y_spacing,
            sp[2] * args.z_spacing
        ])
        vol.mode(int(args.mode)).color(args.cmap).jittering(True)
        # if args.lighting !='default':
        vol.lighting(args.lighting).jittering(True)
        vp = applications.RayCastPlotter(vol)
        vp.show(viewup="z", interactive=True)
        vp.sliders[0][0].SetEnabled(False)
        vp.sliders[1][0].SetEnabled(False)
        vp.sliders[2][0].SetEnabled(False)
        return

    ##########################################################
    # special case of SLC/TIFF/DICOM volumes with --slicer option
    elif args.slicer:
        # print('DEBUG special case of SLC/TIFF/DICOM volumes with --slicer option')

        useSlider3D = False
        if args.axes_type == 4:
            args.axes_type = 1
        elif args.axes_type == 3:
            args.axes_type = 1
            useSlider3D = True

        vol = io.load(args.files[0], force=args.reload)

        sp = vol.spacing()
        vol.spacing([
            sp[0] * args.x_spacing, sp[1] * args.y_spacing,
            sp[2] * args.z_spacing
        ])

        settings.plotter_instance = None  # reset

        plt = applications.SlicerPlotter(
            vol,
            bg='white',
            bg2='lb',
            useSlider3D=useSlider3D,
            cmaps=[args.cmap, "Spectral_r", "hot_r", "bone_r", "gist_ncar_r"],
            alpha=args.alpha,
            axes=args.axes_type,
            clamp=True,
            size=(1000, 800),
        )
        plt.show()
        return

    ########################################################################
    elif args.edit:
        # print('edit mode for meshes and pointclouds')
        settings.plotter_instance = None  # reset
        settings.useParallelProjection = True

        try:
            m = Mesh(args.files[0], alpha=args.alpha / 2, c=args.color)
        except AttributeError:
            printc(
                "In edit mode, input file must be a point cloud or polygonal mesh. Exit.",
                c='r')
            return

        vp = applications.FreeHandCutPlotter(m, splined=True)
        vp.addHoverLegend()
        if not args.background_grad:
            args.background_grad = None
        vp.start(axes=1, bg=args.background, bg2=args.background_grad)

    ########################################################################
    elif args.slicer2d:
        # print('DEBUG special case of SLC/TIFF/DICOM volumes with --slicer2d option')
        vol = io.load(args.files[0], force=args.reload)
        if not vol:
            return
        vol.cmap('bone_r')
        sp = vol.spacing()
        vol.spacing([
            sp[0] * args.x_spacing, sp[1] * args.y_spacing,
            sp[2] * args.z_spacing
        ])
        settings.plotter_instance = None  # reset
        plt = applications.Slicer2d(vol)
        plt.interactor.Start()
        return

    ########################################################################
    # normal mode for single VOXEL file with Isosurface Slider or LEGO mode
    elif nfiles == 1 and (".slc" in args.files[0].lower()
                          or ".vti" in args.files[0].lower()
                          or ".tif" in args.files[0].lower()
                          or ".mhd" in args.files[0].lower()
                          or ".nrrd" in args.files[0].lower()
                          or ".dem" in args.files[0].lower()):
        # print('DEBUG normal mode for single VOXEL file with Isosurface Slider or LEGO mode')
        vol = io.load(args.files[0], force=args.reload)
        sp = vol.spacing()
        vol.spacing([
            sp[0] * args.x_spacing, sp[1] * args.y_spacing,
            sp[2] * args.z_spacing
        ])
        if not args.color:
            args.color = 'gold'
        vp = applications.IsosurfaceBrowser(vol,
                                            lego=args.lego,
                                            c=args.color,
                                            cmap=args.cmap,
                                            delayed=args.lego)
        vp.show(zoom=args.zoom, viewup="z")
        return

    ########################################################################
    # NORMAL mode for single or multiple files, or multiren mode, or numpy scene
    elif nfiles == 1 or (not args.scrolling_mode):
        # print('DEBUG NORMAL mode for single or multiple files, or multiren mode')

        interactor_mode = 0
        if args.image:
            interactor_mode = 'image'

        ##########################################################
        # loading a full scene
        if ".npy" in args.files[0] or ".npz" in args.files[0] and nfiles == 1:

            objct = io.load(args.files[0], force=args.reload)

            if "Plotter" in str(type(objct)):  # loading a full scene
                objct.show(mode=interactor_mode)
                return
            else:  # loading a set of meshes
                vp.show(objct, mode=interactor_mode)
                return
        #########################################################

        ds = 0
        actors = []
        for i in range(N):
            f = args.files[i]

            colb = args.color
            if args.color is None and N > 1:
                colb = i

            actor = load(f, force=args.reload)

            if isinstance(actor, (TetMesh, UGrid)):
                actor = actor.tomesh().shrink(0.975).c(colb).alpha(args.alpha)

            if isinstance(actor, Mesh):
                actors.append(actor)
                actor.c(colb).alpha(args.alpha).wireframe(wire).lighting(
                    args.lighting)
                if args.flat:
                    actor.flat()
                else:
                    actor.phong()

                if i == 0 and args.texture_file:
                    actor.texture(args.texture_file)

                if args.point_size > 0:
                    try:
                        actor.GetProperty().SetPointSize(args.point_size)
                        actor.GetProperty().SetRepresentationToPoints()
                    except AttributeError:
                        pass

                if args.showedges:
                    try:
                        actor.GetProperty().SetEdgeVisibility(1)
                        actor.GetProperty().SetLineWidth(0.1)
                        actor.GetProperty().SetRepresentationToSurface()
                    except AttributeError:
                        pass
            else:
                actors.append(actor)

            if args.multirenderer_mode:
                try:
                    ds = actor.diagonalSize() * 3
                    vp.camera.SetClippingRange(0, ds)
                    vp.show(actor,
                            at=i,
                            interactive=False,
                            zoom=args.zoom,
                            mode=interactor_mode)
                    vp.actors = actors
                except AttributeError:
                    # wildcards in quotes make glob return actor as a list :(
                    printc(
                        "Please do not use wildcards within single or double quotes!",
                        c='r')

        if args.multirenderer_mode:
            vp.interactor.Start()

        else:

            # scene is empty
            if all(a is None for a in actors):
                printc("..could not load file(s). Quit.", c='r')
                return

            vp.show(actors,
                    interactive=True,
                    zoom=args.zoom,
                    mode=interactor_mode)
        return

    ########################################################################
    # scrolling mode  -s
    else:
        #print("DEBUG simple browser mode  -s")
        if vp.axes == 4:
            vp.axes = 1

        acts = vp.load(args.files, force=args.reload)
        for a in acts:
            if hasattr(a, 'c'):  #Picture doesnt have it
                a.c(args.color)
            a.alpha(args.alpha)

        applications.Browser(acts)
        vp.show(interactive=True, zoom=args.zoom)