Ejemplo n.º 1
0
def SplitDisconectedParts(polydata):
    """
    """
    conn = vtk.vtkPolyDataConnectivityFilter()
    conn.SetInputData(polydata)
    conn.SetExtractionModeToAllRegions()
    conn.Update()

    nregions = conn.GetNumberOfExtractedRegions()

    conn.SetExtractionModeToSpecifiedRegions()
    conn.Update()

    polydata_collection = []

    # Update progress value in GUI
    progress = nregions -1
    if progress:
        UpdateProgress = vu.ShowProgress(progress)

    for region in xrange(nregions):
        conn.InitializeSpecifiedRegionList()
        conn.AddSpecifiedRegion(region)
        conn.Update()

        p = vtk.vtkPolyData()
        p.DeepCopy(conn.GetOutput())

        polydata_collection.append(p)
        if progress:
            UpdateProgress(region, _("Splitting disconnected regions..."))

    return polydata_collection
Ejemplo n.º 2
0
def SelectLargestPart(polydata):
    """
    """
    UpdateProgress = vu.ShowProgress(1)
    conn = vtk.vtkPolyDataConnectivityFilter()
    conn.SetInputData(polydata)
    conn.SetExtractionModeToLargestRegion()
    conn.AddObserver("ProgressEvent", lambda obj, evt:
                  UpdateProgress(conn, "Getting largest part..."))
    conn.Update()

    result = vtk.vtkPolyData()
    result.DeepCopy(conn.GetOutput())
    return result
Ejemplo n.º 3
0
def JoinSeedsParts(polydata, point_id_list):
    """
    The function require vtkPolyData and point id
    from vtkPolyData.
    """
    conn = vtk.vtkPolyDataConnectivityFilter()
    conn.SetInputData(polydata)
    conn.SetExtractionModeToPointSeededRegions()
    UpdateProgress = vu.ShowProgress(1 + len(point_id_list))
    pos = 1
    for seed in point_id_list:
        conn.AddSeed(seed)
        UpdateProgress(pos, _("Analysing selected regions..."))
        pos += 1

    conn.AddObserver("ProgressEvent", lambda obj, evt:
                  UpdateProgress(conn, "Getting selected parts"))
    conn.Update()

    result = vtk.vtkPolyData()
    result.DeepCopy(conn.GetOutput())
    return result
Ejemplo n.º 4
0
    def AddNewActor(self, pubsub_evt):
        """
        Create surface actor, save into project and send it to viewer.
        """
        slice_, mask, surface_parameters = pubsub_evt.data
        matrix = slice_.matrix
        filename_img = slice_.matrix_filename
        spacing = slice_.spacing

        algorithm = surface_parameters['method']['algorithm']
        options = surface_parameters['method']['options']

        surface_name = surface_parameters['options']['name']
        quality = surface_parameters['options']['quality']
        fill_holes = surface_parameters['options']['fill']
        keep_largest = surface_parameters['options']['keep_largest']

        mode = 'CONTOUR'  # 'GRAYSCALE'
        min_value, max_value = mask.threshold_range
        colour = mask.colour

        try:
            overwrite = surface_parameters['options']['overwrite']
        except KeyError:
            overwrite = False
        mask.matrix.flush()

        if quality in const.SURFACE_QUALITY.keys():
            imagedata_resolution = const.SURFACE_QUALITY[quality][0]
            smooth_iterations = const.SURFACE_QUALITY[quality][1]
            smooth_relaxation_factor = const.SURFACE_QUALITY[quality][2]
            decimate_reduction = const.SURFACE_QUALITY[quality][3]

        #if imagedata_resolution:
        #imagedata = iu.ResampleImage3D(imagedata, imagedata_resolution)

        pipeline_size = 4
        if decimate_reduction:
            pipeline_size += 1
        if (smooth_iterations and smooth_relaxation_factor):
            pipeline_size += 1
        if fill_holes:
            pipeline_size += 1
        if keep_largest:
            pipeline_size += 1

        ## Update progress value in GUI
        UpdateProgress = vu.ShowProgress(pipeline_size)
        UpdateProgress(0, _("Creating 3D surface..."))

        language = ses.Session().language

        if (prj.Project().original_orientation == const.CORONAL):
            flip_image = False
        else:
            flip_image = True

        n_processors = multiprocessing.cpu_count()

        pipe_in, pipe_out = multiprocessing.Pipe()
        o_piece = 1
        piece_size = 2000

        n_pieces = int(round(matrix.shape[0] / piece_size + 0.5, 0))

        q_in = multiprocessing.Queue()
        q_out = multiprocessing.Queue()

        p = []
        for i in xrange(n_processors):
            sp = surface_process.SurfaceProcess(
                pipe_in, filename_img, matrix.shape, matrix.dtype,
                mask.temp_file, mask.matrix.shape, mask.matrix.dtype, spacing,
                mode, min_value, max_value, decimate_reduction,
                smooth_relaxation_factor, smooth_iterations, language,
                flip_image, q_in, q_out, algorithm != 'Default', algorithm,
                imagedata_resolution)
            p.append(sp)
            sp.start()

        for i in xrange(n_pieces):
            init = i * piece_size
            end = init + piece_size + o_piece
            roi = slice(init, end)
            q_in.put(roi)
            print "new_piece", roi

        for i in p:
            q_in.put(None)

        none_count = 1
        while 1:
            msg = pipe_out.recv()
            if (msg is None):
                none_count += 1
            else:
                UpdateProgress(msg[0] / (n_pieces * pipeline_size), msg[1])

            if none_count > n_pieces:
                break

        polydata_append = vtk.vtkAppendPolyData()
        #  polydata_append.ReleaseDataFlagOn()
        t = n_pieces
        while t:
            filename_polydata = q_out.get()

            reader = vtk.vtkXMLPolyDataReader()
            reader.SetFileName(filename_polydata)
            #  reader.ReleaseDataFlagOn()
            reader.Update()
            #  reader.GetOutput().ReleaseDataFlagOn()

            polydata = reader.GetOutput()
            #  polydata.SetSource(None)

            polydata_append.AddInputData(polydata)
            del reader
            del polydata
            t -= 1

        polydata_append.Update()
        #  polydata_append.GetOutput().ReleaseDataFlagOn()
        polydata = polydata_append.GetOutput()
        #polydata.Register(None)
        #  polydata.SetSource(None)
        del polydata_append

        if algorithm == 'ca_smoothing':
            normals = vtk.vtkPolyDataNormals()
            normals_ref = weakref.ref(normals)
            normals_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    normals_ref(), _("Creating 3D surface...")))
            normals.SetInputData(polydata)
            #  normals.ReleaseDataFlagOn()
            #normals.SetFeatureAngle(80)
            #normals.AutoOrientNormalsOn()
            normals.ComputeCellNormalsOn()
            #  normals.GetOutput().ReleaseDataFlagOn()
            normals.Update()
            del polydata
            polydata = normals.GetOutput()
            #  polydata.SetSource(None)
            del normals

            clean = vtk.vtkCleanPolyData()
            #  clean.ReleaseDataFlagOn()
            #  clean.GetOutput().ReleaseDataFlagOn()
            clean_ref = weakref.ref(clean)
            clean_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    clean_ref(), _("Creating 3D surface...")))
            clean.SetInputData(polydata)
            clean.PointMergingOn()
            clean.Update()

            del polydata
            polydata = clean.GetOutput()
            #  polydata.SetSource(None)
            del clean

            try:
                polydata.BuildLinks()
            except TypeError:
                polydata.BuildLinks(0)
            polydata = ca_smoothing.ca_smoothing(polydata, options['angle'],
                                                 options['max distance'],
                                                 options['min weight'],
                                                 options['steps'])
            #  polydata.SetSource(None)
            #  polydata.DebugOn()

        else:
            #smoother = vtk.vtkWindowedSincPolyDataFilter()
            smoother = vtk.vtkSmoothPolyDataFilter()
            smoother_ref = weakref.ref(smoother)
            smoother_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    smoother_ref(), _("Creating 3D surface...")))
            smoother.SetInputData(polydata)
            smoother.SetNumberOfIterations(smooth_iterations)
            smoother.SetRelaxationFactor(smooth_relaxation_factor)
            smoother.SetFeatureAngle(80)
            #smoother.SetEdgeAngle(90.0)
            #smoother.SetPassBand(0.1)
            smoother.BoundarySmoothingOn()
            smoother.FeatureEdgeSmoothingOn()
            #smoother.NormalizeCoordinatesOn()
            #smoother.NonManifoldSmoothingOn()
            #  smoother.ReleaseDataFlagOn()
            #  smoother.GetOutput().ReleaseDataFlagOn()
            smoother.Update()
            del polydata
            polydata = smoother.GetOutput()
            #polydata.Register(None)
            #  polydata.SetSource(None)
            del smoother

        if decimate_reduction:
            print "Decimating", decimate_reduction
            decimation = vtk.vtkQuadricDecimation()
            #  decimation.ReleaseDataFlagOn()
            decimation.SetInputData(polydata)
            decimation.SetTargetReduction(decimate_reduction)
            decimation_ref = weakref.ref(decimation)
            decimation_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    decimation_ref(), _("Creating 3D surface...")))
            #decimation.PreserveTopologyOn()
            #decimation.SplittingOff()
            #decimation.BoundaryVertexDeletionOff()
            #  decimation.GetOutput().ReleaseDataFlagOn()
            decimation.Update()
            del polydata
            polydata = decimation.GetOutput()
            #polydata.Register(None)
            #  polydata.SetSource(None)
            del decimation

        to_measure = polydata
        #to_measure.Register(None)
        #  to_measure.SetSource(None)

        if keep_largest:
            conn = vtk.vtkPolyDataConnectivityFilter()
            conn.SetInputData(polydata)
            conn.SetExtractionModeToLargestRegion()
            conn_ref = weakref.ref(conn)
            conn_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    conn_ref(), _("Creating 3D surface...")))
            conn.Update()
            #  conn.GetOutput().ReleaseDataFlagOn()
            del polydata
            polydata = conn.GetOutput()
            #polydata.Register(None)
            #  polydata.SetSource(None)
            del conn

        #Filter used to detect and fill holes. Only fill boundary edges holes.
        #TODO: Hey! This piece of code is the same from
        #polydata_utils.FillSurfaceHole, we need to review this.
        if fill_holes:
            filled_polydata = vtk.vtkFillHolesFilter()
            #  filled_polydata.ReleaseDataFlagOn()
            filled_polydata.SetInputData(polydata)
            filled_polydata.SetHoleSize(300)
            filled_polydata_ref = weakref.ref(filled_polydata)
            filled_polydata_ref().AddObserver(
                "ProgressEvent", lambda obj, evt: UpdateProgress(
                    filled_polydata_ref(), _("Creating 3D surface...")))
            filled_polydata.Update()
            #  filled_polydata.GetOutput().ReleaseDataFlagOn()
            del polydata
            polydata = filled_polydata.GetOutput()
            #polydata.Register(None)
            #  polydata.SetSource(None)
            #  polydata.DebugOn()
            del filled_polydata

        normals = vtk.vtkPolyDataNormals()
        #  normals.ReleaseDataFlagOn()
        normals_ref = weakref.ref(normals)
        normals_ref().AddObserver(
            "ProgressEvent", lambda obj, evt: UpdateProgress(
                normals_ref(), _("Creating 3D surface...")))
        normals.SetInputData(polydata)
        normals.SetFeatureAngle(80)
        normals.AutoOrientNormalsOn()
        #  normals.GetOutput().ReleaseDataFlagOn()
        normals.Update()
        del polydata
        polydata = normals.GetOutput()
        #polydata.Register(None)
        #  polydata.SetSource(None)
        del normals

        # Improve performance
        stripper = vtk.vtkStripper()
        #  stripper.ReleaseDataFlagOn()
        stripper_ref = weakref.ref(stripper)
        stripper_ref().AddObserver(
            "ProgressEvent", lambda obj, evt: UpdateProgress(
                stripper_ref(), _("Creating 3D surface...")))
        stripper.SetInputData(polydata)
        stripper.PassThroughCellIdsOn()
        stripper.PassThroughPointIdsOn()
        #  stripper.GetOutput().ReleaseDataFlagOn()
        stripper.Update()
        del polydata
        polydata = stripper.GetOutput()
        #polydata.Register(None)
        #  polydata.SetSource(None)
        del stripper

        # Map polygonal data (vtkPolyData) to graphics primitives.
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputData(polydata)
        mapper.ScalarVisibilityOff()
        #  mapper.ReleaseDataFlagOn()
        mapper.ImmediateModeRenderingOn()  # improve performance

        # Represent an object (geometry & properties) in the rendered scene
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        del mapper
        #Create Surface instance
        if overwrite:
            surface = Surface(index=self.last_surface_index)
        else:
            surface = Surface(name=surface_name)
        surface.colour = colour
        surface.polydata = polydata
        del polydata

        # Set actor colour and transparency
        actor.GetProperty().SetColor(colour)
        actor.GetProperty().SetOpacity(1 - surface.transparency)

        prop = actor.GetProperty()

        interpolation = int(ses.Session().surface_interpolation)

        prop.SetInterpolation(interpolation)

        proj = prj.Project()
        if overwrite:
            proj.ChangeSurface(surface)
        else:
            index = proj.AddSurface(surface)
            surface.index = index
            self.last_surface_index = index

        session = ses.Session()
        session.ChangeProject()

        # The following lines have to be here, otherwise all volumes disappear
        measured_polydata = vtk.vtkMassProperties()
        #  measured_polydata.ReleaseDataFlagOn()
        measured_polydata.SetInputData(to_measure)
        volume = float(measured_polydata.GetVolume())
        area = float(measured_polydata.GetSurfaceArea())
        surface.volume = volume
        surface.area = area
        self.last_surface_index = surface.index
        del measured_polydata
        del to_measure

        Publisher.sendMessage('Load surface actor into viewer', actor)

        # Send actor by pubsub to viewer's render
        if overwrite and self.actors_dict.keys():
            old_actor = self.actors_dict[self.last_surface_index]
            Publisher.sendMessage('Remove surface actor from viewer',
                                  old_actor)

        # Save actor for future management tasks
        self.actors_dict[surface.index] = actor

        Publisher.sendMessage(
            'Update surface info in GUI',
            (surface.index, surface.name, surface.colour, surface.volume,
             surface.area, surface.transparency))

        #When you finalize the progress. The bar is cleaned.
        UpdateProgress = vu.ShowProgress(1)
        UpdateProgress(0, _("Ready"))
        Publisher.sendMessage('Update status text in GUI', _("Ready"))

        Publisher.sendMessage('End busy cursor')
        del actor
Ejemplo n.º 5
0
#    QUALQUER GARANTIA; sem mesmo a garantia implicita de
#    COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM
#    PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
#    detalhes.
#--------------------------------------------------------------------------

import sys

import vtk
import wx
from wx.lib.pubsub import pub as Publisher

import vtk_utils as vu

# Update progress value in GUI
UpdateProgress = vu.ShowProgress()

def ApplyDecimationFilter(polydata, reduction_factor):
    """
    Reduce number of triangles of the given vtkPolyData, based on
    reduction_factor.
    """
    # Important: vtkQuadricDecimation presented better results than
    # vtkDecimatePro
    decimation = vtk.vtkQuadricDecimation()
    decimation.SetInputData(polydata)
    decimation.SetTargetReduction(reduction_factor)
    decimation.GetOutput().ReleaseDataFlagOn()
    decimation.AddObserver("ProgressEvent", lambda obj, evt:
                  UpdateProgress(decimation, "Reducing number of triangles..."))
    return decimation.GetOutput()