Exemple #1
0
def reduceMesh(mymesh, reductionFactor):
    """Reduce the number of triangles in a mesh using VTK's QuadricDecimation filter."""
    try:
        t = time.perf_counter()
        deci = vtk.vtkQuadricDecimation()
        deci.SetTargetReduction(reductionFactor)
        if vtk.vtkVersion.GetVTKMajorVersion() >= 6:
            deci.SetInputData(mymesh)
        else:
            deci.SetInput(mymesh)
        deci.Update()
        print("Surface reduced")
        m2 = deci.GetOutput()
        del deci
        deci = None
        print("    ", m2.GetNumberOfPolys(), "polygons")
        elapsedTime(t)
        return m2
    except:
        print("Surface reduction failed")
        exc_type, exc_value, exc_traceback = sys.exc_info()
        traceback.print_exception(exc_type,
                                  exc_value,
                                  exc_traceback,
                                  limit=2,
                                  file=sys.stdout)
    return None
Exemple #2
0
    def Decimate(self, target_reduction):
        """
        Reduces the number of triangles in a triangular mesh using
        vtkQuadricDecimation.

        Parameters
        ----------
        mesh : vtk.PolyData
            Mesh to decimate

        target_reduction : float Fraction of the original mesh to remove.
            TargetReduction is set to 0.9, this filter will try to reduce
            the data set to 10% of its original size and will remove 90%
            of the input triangles.

        Returns
        -------
        outmesh : vtkInterface.PolyData
            Decimated mesh

        """
        # create decimation filter
        decimate = vtk.vtkQuadricDecimation()  # vtkDecimatePro as well
        decimate.SetInputData(self)
        decimate.SetTargetReduction(target_reduction)
        decimate.Update()
        return PolyData(decimate.GetOutput())
def create_mesh(label_pix, labels_to_use, inds_to_phys=None):
    # convert the numpy representation to VTK, so we can create a mesh
    # using marching cubes for display later
    vtk_import = vtkImageImport()
    vtk_import.SetImportVoidPointer(label_pix, True)
    vtk_import.SetDataScalarType(VTK_UNSIGNED_CHAR)
    vtk_import.SetNumberOfScalarComponents(1)

    vtk_import.SetDataExtent(0, label_pix.shape[2] - 1, 0,
                             label_pix.shape[1] - 1, 0, label_pix.shape[0] - 1)

    vtk_import.SetWholeExtent(0, label_pix.shape[2] - 1, 0,
                              label_pix.shape[1] - 1, 0,
                              label_pix.shape[0] - 1)

    vtk_import.Update()

    flipper = vtkImageFlip()
    flipper.SetInputData(vtk_import.GetOutput())
    flipper.SetFilteredAxis(1)
    flipper.FlipAboutOriginOff()
    flipper.Update()

    vtk_img = flipper.GetOutput()

    marching_cubes = vtkDiscreteMarchingCubes()
    marching_cubes.SetInputData(vtk_img)

    num_labels_to_use = len(labels_to_use)

    marching_cubes.SetNumberOfContours(num_labels_to_use)

    for i in range(num_labels_to_use):
        marching_cubes.SetValue(i, labels_to_use[i])

    marching_cubes.Update()

    smoother = vtkWindowedSincPolyDataFilter()
    smoother.SetInputData(marching_cubes.GetOutput())
    smoother.SetNumberOfIterations(25)
    smoother.SetPassBand(0.1)
    smoother.SetBoundarySmoothing(False)
    smoother.SetFeatureEdgeSmoothing(False)
    smoother.SetFeatureAngle(120.0)
    smoother.SetNonManifoldSmoothing(True)
    smoother.NormalizeCoordinatesOn()
    smoother.Update()

    mesh_reduce = vtkQuadricDecimation()
    mesh_reduce.SetInputData(smoother.GetOutput())
    mesh_reduce.SetTargetReduction(0.25)
    mesh_reduce.Update()

    vertex_xform = np.mat(np.eye(4))
    vertex_xform[1, 1] = -1
    vertex_xform[1, 3] = label_pix.shape[1] + 1

    vertex_xform = inds_to_phys * vertex_xform

    return xform_mesh(mesh_reduce.GetOutput(), vertex_xform)
def eval_decimation(_reduction, _model):
    deci = vtk.vtkQuadricDecimation()
    deci.SetInputConnection(_model.mesh.GetOutputPort())
    deci.VolumePreservationOn()
    deci.SetTargetReduction(_reduction / 100)  # percent of removed triangles
    deci.Update()
    return deci.GetOutput().GetNumberOfPoints()
def run(neuron_num):
    file = "meshes-with-axons-filled-assembled/n%02d.vtp" % neuron_num

    readerVolume = vtk.vtkXMLPolyDataReader()
    readerVolume.SetFileName(file)
    readerVolume.Update()

    decimate = readerVolume
    nlod = 5

    for i in range(nlod):
        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputConnection(decimate.GetOutputPort())
        smoother.SetNumberOfIterations(20)  # This has little effect on the error!
        smoother.BoundarySmoothingOff()
        smoother.FeatureEdgeSmoothingOff()
        smoother.SetPassBand(.1)        # This increases the error a lot! .001
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.GenerateErrorScalarsOn()
        smoother.Update()

        decimate = vtk.vtkQuadricDecimation ()
        decimate.SetInputData(smoother.GetOutput())
        decimate.SetTargetReduction(.7)
        decimate.Update()


        full_out_name = 'meshes-with-axons-filled-assembled-lod/n%02d_LOD%d.obj' % (neuron_num, i - 1)
        writer = vtk.vtkOBJWriter()
        writer.SetFileName(full_out_name)
        writer.SetInputData(decimate.GetOutput())
        writer.Write()
def simplify_polydata(polydata, num_simplify_iter=0, smooth=False):
    for simplify_iter in range(num_simplify_iter):

        t = time.time()

        deci = vtk.vtkQuadricDecimation()
        deci.SetInputData(polydata)

        deci.SetTargetReduction(0.8)
        # 0.8 means each iteration causes the point number to drop to 20% the original

        deci.Update()

        polydata = deci.GetOutput()

        if smooth:

            smoother = vtk.vtkWindowedSincPolyDataFilter()
            #         smoother.NormalizeCoordinatesOn()
            smoother.SetPassBand(.1)
            smoother.SetNumberOfIterations(20)
            smoother.SetInputData(polydata)
            smoother.Update()

            polydata = smoother.GetOutput()

        n_pts = polydata.GetNumberOfPoints()

        if polydata.GetNumberOfPoints() < 200:
            break

        sys.stderr.write('simplify %d @ %d: %.2f seconds\n' %
                         (simplify_iter, n_pts, time.time() - t))  #

    return polydata
 def __init__(self, module_manager):
     SimpleVTKClassModuleBase.__init__(
         self, module_manager,
         vtk.vtkQuadricDecimation(), 'Processing.',
         ('vtkPolyData',), ('vtkPolyData',),
         replaceDoc=True,
         inputFunctions=None, outputFunctions=None)
Exemple #8
0
def extract_smooth_mesh(imageVTK,
                        label_range,
                        smoothing_iterations=30,
                        pass_band_param=0.01,
                        target_reduction=0.95):
    '''Extract mesh/contour for labels in imageVTK, smooth and decimate.
    
    Multiple labels can be extracted at once, however touching labels 
    will share vertices and the label ids are lost during smoothing/decimation.
    Processing is slow for small objects in a large volume and should be cropped beforehand.
    
    Args:
        imageVTK: vtk image data
        label_range: range of labels to extract. A tuple (l,l) will extract 
            a mesh for a single label id l
        smoothing_iterations: number of iterations for vtkWindowedSincPolyDataFilter
        pass_band_param: pass band param in range [0.,2.] for vtkWindowedSincPolyDataFilter.
            Lower value remove higher frequencies.
        target_reduction: target reduction for vtkQuadricDecimation
    '''

    n_contours = label_range[1] - label_range[0] + 1

    # alternative vtkDiscreteMarchingCubes is slower and creates some weird missalignment lines when applied to tight crops
    dfe = vtk.vtkDiscreteFlyingEdges3D()
    dfe.SetInputData(imageVTK)
    dfe.ComputeScalarsOff(
    )  # numpy image labels --> cells (faces) scalar values
    dfe.ComputeNormalsOff()
    dfe.ComputeGradientsOff()
    dfe.InterpolateAttributesOff()
    dfe.GenerateValues(n_contours, label_range[0],
                       label_range[1])  # numContours, rangeStart, rangeEnd
    dfe.Update()

    smoother = vtk.vtkWindowedSincPolyDataFilter()
    smoother.SetInputConnection(dfe.GetOutputPort())
    smoother.SetNumberOfIterations(
        smoothing_iterations)  #this has little effect on the error!
    smoother.BoundarySmoothingOff()
    smoother.FeatureEdgeSmoothingOff()
    # smoother.SetFeatureAngle(120)
    smoother.SetPassBand(
        pass_band_param)  # from 0 to 2, 2 keeps high frequencies
    smoother.NonManifoldSmoothingOn()
    smoother.NormalizeCoordinatesOn()
    smoother.GenerateErrorScalarsOff()
    smoother.GenerateErrorVectorsOff()
    smoother.Update()

    # vtkQuadricDecimation looks cleaner than vtkDecimatePro (no unexpected sharp edges)
    # but drop points scalar value --> can be added back if doing one instance a time
    decimate = vtk.vtkQuadricDecimation()
    decimate.SetInputConnection(smoother.GetOutputPort())
    decimate.SetTargetReduction(target_reduction)
    decimate.VolumePreservationOn()
    decimate.Update()

    return decimate.GetOutput()
 def decimation(self, reduction=50):
     decimation = vtk.vtkQuadricDecimation()
     decimation.SetInputConnection(self.mesh.GetOutputPort())
     decimation.VolumePreservationOn()
     decimation.SetTargetReduction(reduction /
                                   100)  # percent of removed triangles
     decimation.Update()
     self.mesh = decimation
 def __init__(self, module_manager):
     SimpleVTKClassModuleBase.__init__(self,
                                       module_manager,
                                       vtk.vtkQuadricDecimation(),
                                       'Processing.', ('vtkPolyData', ),
                                       ('vtkPolyData', ),
                                       replaceDoc=True,
                                       inputFunctions=None,
                                       outputFunctions=None)
Exemple #11
0
def MarchingCubes(image,threshold):

    # marching cubes
    mc = vtk.vtkMarchingCubes()
    mc.SetInputData(image)
    mc.ComputeNormalsOn()
    mc.ComputeGradientsOn()
    mc.SetValue(0, threshold)
    mc.Update()

    # To remain largest region
    #confilter = vtk.vtkPolyDataConnectivityFilter()
    #confilter.SetInputData(mc.GetOutput())
    #confilter.SetExtractionModeToLargestRegion()
    #confilter.Update()

    # reduce poly data
    inputPoly = vtk.vtkPolyData()
    inputPoly.ShallowCopy(mc.GetOutput())

    print("Before decimation\n"
          "-----------------\n"
          "There are " + str(inputPoly.GetNumberOfPoints()) + "points.\n"
          "There are " + str(inputPoly.GetNumberOfPolys()) + "polygons.\n")

    #decimate = vtk.vtkDecimatePro()
    decimate = vtk.vtkQuadricDecimation()
    decimate.SetInputData(inputPoly)
    decimate.SetTargetReduction(.90)
    decimate.Update()

    decimatedPoly = vtk.vtkPolyData()
    decimatedPoly.ShallowCopy(decimate.GetOutput())

    print("After decimation \n"
          "-----------------\n"
          "There are " + str(decimatedPoly.GetNumberOfPoints()) + "points.\n"
          "There are " + str(decimatedPoly.GetNumberOfPolys()) + "polygons.\n")

    # smooth surface
    smoothFilter = vtk.vtkSmoothPolyDataFilter()
    smoothFilter.SetInputData(decimatedPoly)
    smoothFilter.SetNumberOfIterations(15)
    smoothFilter.SetRelaxationFactor(0.1)
    smoothFilter.FeatureEdgeSmoothingOff()
    smoothFilter.BoundarySmoothingOn()
    smoothFilter.Update()

    decimatedPoly = vtk.vtkPolyData()
    decimatedPoly.ShallowCopy(smoothFilter.GetOutput())

    return decimatedPoly#confilter.GetOutput()
Exemple #12
0
 def mesh_decimation(self, reduction_rate):
     decimate_reader = vtk.vtkQuadricDecimation()
     decimate_reader.SetInputData(self.vtkPolyData)
     decimate_reader.SetTargetReduction(reduction_rate)
     decimate_reader.VolumePreservationOn()
     decimate_reader.Update()
     self.vtkPolyData = decimate_reader.GetOutput()
     self.get_mesh_data_from_vtkPolyData()
     if self.warning:
         print(
             'Warning! self.cell_attributes are reset and need to be updated!'
         )
     self.cell_attributes = dict()  #reset
     self.point_attributes = dict()  #reset
def quadric_decimation(data,ratio):
    sim = vtk.vtkQuadricDecimation();
    sim.SetTargetReduction(ratio);
    sim.SetInputData(data);
    """
    sim.AttributeErrorMetricOn();
    sim.VectorsAttributeOff();
    sim.NormalsAttributeOn();
    sim.TensorsAttributeOff();
    sim.TCoordsAttributeOff();
    sim.ScalarsAttributeOff();
    """
    sim.Update()
    return sim.GetOutput();
Exemple #14
0
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()
Exemple #15
0
def decimation(poly, rate):
    """
    Simplifies a VTK PolyData
    Args: 
        poly: vtk PolyData
        rate: target rate reduction
    """
    decimate = vtk.vtkQuadricDecimation()
    decimate.SetInputData(poly)
    decimate.AttributeErrorMetricOn()
    decimate.ScalarsAttributeOn()
    decimate.SetTargetReduction(rate)
    decimate.VolumePreservationOff()
    decimate.Update()
    output = decimate.GetOutput()
    #output = cleanPolyData(output, 0.)
    return output
 def get(self):
     volumeData = self.reader.get("SURF", self.subj, name=self.get_argument("name", None), scalars="aparc")
     
     decimate = vtk.vtkQuadricDecimation()
     decimate.SetInputData(volumeData)
     decimate.SetTargetReduction(float(self.get_argument("res", 0)))
     decimate.Update()                
     volumeData2 = decimate.GetOutput()            
     volumeData2 = volumeData
     
     resultado = {}
     resultado['subject'] = self.subj
     resultado['type'] = 'volume'
     resultado['bounds'] = volumeData2.GetBounds()
     resultado['points'] = numpy_support.vtk_to_numpy(volumeData2.GetPoints().GetData()).flatten().tolist()
     resultado['faces'] = np.delete(numpy_support.vtk_to_numpy(volumeData2.GetPolys().GetData()), slice(None, None, 4)).tolist()
     resultado['scalars'] = numpy_support.vtk_to_numpy(volumeData2.GetPointData().GetScalars()).flatten().tolist()
     self.set_header("Content-Type","application/json")
     self.write(json.dumps(resultado, separators=(',',':')))        
Exemple #17
0
def decimate_mesh(V, F, params, fun=None):
    """Decimate mesh by a given factor
        
        Returns deccimated arrays Vd (vertices), Fd (faces) and optionally Fund (functional values)
        """
    factor = params['factor']
    Vol_preser = params['Vol_preser']

    F2 = F.flatten()
    F2 = np.insert(F2, range(0, len(F2), 3), int(3), axis=0)

    vtk_mesh = createPolyData(V, F2, fun)
    decimate = vtk.vtkQuadricDecimation()
    decimate.SetInputData(vtk_mesh)
    decimate.SetTargetReduction(factor)
    decimate.SetVolumePreservation(Vol_preser)

    if fun is not None:
        Fun_Error_Metric = params['Fun_Error_Metric']
        Fun_weight = params['Fun_weigth']
        decimate.SetAttributeErrorMetric(Fun_Error_Metric)
        decimate.SetScalarsWeight(Fun_weight)

    decimate.Update()

    decimated = vtk.vtkPolyData()
    decimated.ShallowCopy(decimate.GetOutput())

    Vd_vtk = decimated.GetPoints().GetData()
    Vd = numpy_support.vtk_to_numpy(Vd_vtk)
    Fd_vtk = decimated.GetPolys().GetData()
    Fd = numpy_support.vtk_to_numpy(Fd_vtk)
    Fd = np.delete(Fd, slice(None, None, 4))
    Fd = Fd.reshape(int(len(Fd) / 3), 3)

    if fun is not None:
        fund_vtk = decimated.GetPointData().GetScalars()
        fund = numpy_support.vtk_to_numpy(fund_vtk)
        return Vd, Fd, fund

    else:
        return Vd, Fd
Exemple #18
0
def reduceMesh(mymesh, reductionFactor):
    try:
        deci = vtk.vtkQuadricDecimation()
        deci.SetTargetReduction(reductionFactor)
        if vtk.vtkVersion.GetVTKMajorVersion() >= 6:
            deci.SetInputData(mymesh)
        else:
            deci.SetInput(mymesh)
        deci.Update()
        print("Surface reduced")
        m2 = deci.GetOutput()
        del deci
        print("    ", m2.GetNumberOfPolys(), "polygons")
        return m2
    except:
        print("Surface reduction failed")
        exc_type, exc_value, exc_traceback = sys.exc_info()
        traceback.print_exception(
            exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout)
    return None
Exemple #19
0
def decimate_mesh(mesh, reduction=0.75, type_reduction='quadric', **kwargs):
    """
    Decimate this mesh specifying the percentage (0,1) of triangles to
    be removed

    Parameters
    ----------
    reduction: float (default: 0.75) 
               The percentage of triangles to be removed. 
               It should be in (0, 1)

    type_reduction : str (default: quadric)
                     The type of decimation as:
                         'quadric' : Quadric decimation
                         'progressive : Progressive decimation
    Returns
    -------
    mesh : :map:`TriMesh`
        A new mesh that has been decimated.
    """
    import vtk
    if type_reduction == 'quadric':
        decimate = vtk.vtkQuadricDecimation()
    elif type_reduction == 'progressive':
        decimate = vtk.vtkDecimatePro()
    else:
        raise Exception(
            'Wrong type of reduction. It should be quadric or progressive')

    inputPolyData = trimesh_to_vtk(mesh)
    decimate.SetInputData(inputPolyData)
    decimate.SetTargetReduction(reduction)

    if kwargs.get('preserve_topology',
                  False) and type_reduction == 'progressive':
        decimate.PreserveTopologyOn()

    decimate.Update()

    return trimesh_from_vtk(decimate.GetOutput())
Exemple #20
0
def reduceMesh(mymesh, reductionFactor):
    try:
        t = time.clock()
        deci = vtk.vtkQuadricDecimation()
        deci.SetTargetReduction( reductionFactor )
        if vtk.vtkVersion.GetVTKMajorVersion() >= 6:
            deci.SetInputData( mymesh )
        else:
            deci.SetInput( mymesh )
        deci.Update()
        print ("Surface reduced")
        m2 = deci.GetOutput()
        del deci
        deci = None
        print "    ", m2.GetNumberOfPolys(), "polygons"
        elapsedTime(t)
        return m2
    except:
        print "Surface reduction failed"
        exc_type, exc_value, exc_traceback = sys.exc_info()
        traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout)
    return None
def decimate(poly_data, reduction, data_is_big):
    decimator = None
    #decimator = vtk.vtkDecimatePro()
    #decimator.PreserveTopologyOn()
    #decimator.SplittingOff()
    #decimator.BoundaryVertexDeletionOff()
    #decimator.SetMaximumError(vtk.VTK_DOUBLE_MAX)
    if data_is_big:
        decimator = vtk.vtkQuadricClustering()
        decimator.SetNumberOfXDivisions(1024)
        decimator.SetNumberOfYDivisions(1024)
        decimator.SetNumberOfZDivisions(1024)
    else:
        decimator = vtk.vtkQuadricDecimation()
        decimator.SetTargetReduction(reduction)
    decimator.SetInputData(poly_data)
    decimator.Update()

    decimated = vtk.vtkPolyData()
    decimated.ShallowCopy(decimator.GetOutput())
    print("Decimated:", decimated.GetNumberOfPoints(), "points",
          decimated.GetNumberOfPolys(), "polygons, by ", type(decimator))
    # draw(decimated, color_scale='Rainbow', write_file=True, file_name='after.png')
    return decimated
Exemple #22
0
def main():
    parser = argparse.ArgumentParser(
        description='Convert label image into polygon mesh files.')
    parser.add_argument('input', help='Input filename', metavar='<input>')
    parser.add_argument(
        '-o',
        '--output',
        help='Output filename. Optional. Defaulted to input filename.',
        metavar='<output>')
    parser.add_argument('--ext',
                        help='File extension. Default:%(default)s',
                        metavar='<extension>',
                        default='vtk')
    parser.add_argument('--reduce',
                        help='Target reduction rate. Default:%(default)s',
                        metavar='<rate>',
                        default=0.9,
                        type=float)
    parser.add_argument(
        '--smooth',
        help='# of iteration for smoothing. Default:%(default)s',
        metavar='<n>',
        default=10,
        type=int)
    parser.add_argument('--cap',
                        help="Cap on the image border",
                        action='store_true')

    args = parser.parse_args()

    if args.output is None:
        output_format = os.path.splitext(os.path.basename(
            args.input))[0] + '_{}.' + args.ext
    reader = vtk.vtkMetaImageReader()
    reader.SetFileName(args.input)
    reader.Update()
    n_labels = int(reader.GetOutput().GetScalarRange()[1])

    contour = vtk.vtkDiscreteMarchingCubes()
    if args.cap:
        padder = vtk.vtkImageConstantPad()
        padder.SetInputConnection(reader.GetOutputPort())
        padder.SetConstant(0)
        extent = reader.GetOutput().GetExtent()
        padder.SetOutputWholeExtent(-1, extent[1] + 1, -1, extent[3] + 1, -1,
                                    extent[5] + 1)
        contour.SetInputConnection(padder.GetOutputPort())
    else:
        contour.SetInputConnection(reader.GetOutputPort())
    contour.ComputeNormalsOff()

    writer = {
        'vtk': vtk.vtkPolyDataWriter,
        'ply': vtk.vtkPLYWriter,
        'stl': vtk.vtkSTLWriter
    }.get(args.ext, lambda:
          (print('Unknown file type:' + args.ext), sys.exit(1)))()
    writer.SetFileTypeToBinary()

    for index in tqdm.trange(1, n_labels + 1):
        contour.SetValue(0, index)
        contour.Update()

        decimate = vtk.vtkQuadricDecimation()
        decimate.SetInputConnection(contour.GetOutputPort())
        decimate.SetTargetReduction(args.reduce)
        decimate.Update()

        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputConnection(decimate.GetOutputPort())
        smoother.SetNumberOfIterations(args.smooth)
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.Update()

        normals = vtk.vtkPolyDataNormals()
        normals.SetInputData(smoother.GetOutput())
        normals.ComputePointNormalsOn()
        normals.ComputeCellNormalsOff()
        normals.SplittingOff()
        normals.ConsistencyOn()
        normals.Update()

        writer.SetFileName(output_format.format(index))
        writer.SetInputData(normals.GetOutput())
        writer.Write()
Exemple #23
0
pl3d.SetQFileName("" + str(VTK_DATA_ROOT) + "/Data/combq.bin")
pl3d.SetScalarFunctionNumber(100)
pl3d.SetVectorFunctionNumber(202)
pl3d.Update()
pl3d_output = pl3d.GetOutput().GetBlock(0)
gf = vtk.vtkGeometryFilter()
gf.SetInputData(pl3d_output)
tf = vtk.vtkTriangleFilter()
tf.SetInputConnection(gf.GetOutputPort())
gMapper = vtk.vtkPolyDataMapper()
gMapper.SetInputConnection(gf.GetOutputPort())
gMapper.SetScalarRange(pl3d_output.GetScalarRange())
gActor = vtk.vtkActor()
gActor.SetMapper(gMapper)
# Don't look at attributes
mesh = vtk.vtkQuadricDecimation()
mesh.SetInputConnection(tf.GetOutputPort())
mesh.SetTargetReduction(.90)
mesh.AttributeErrorMetricOn()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(mesh.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# This time worry about attributes
mesh2 = vtk.vtkQuadricDecimation()
mesh2.SetInputConnection(tf.GetOutputPort())
mesh2.SetTargetReduction(.90)
mesh2.AttributeErrorMetricOff()
mapper2 = vtk.vtkPolyDataMapper()
mapper2.SetInputConnection(mesh2.GetOutputPort())
actor2 = vtk.vtkActor()
Exemple #24
0
def vtkQuadricDecimation(poly, targetReduction):
    deci = vtk.vtkQuadricDecimation()
    deci.SetInput(poly)
    deci.SetTargetReduction(targetReduction)
    return deci.GetOutput()
Exemple #25
0
    print("\nERROR: zero cells in mesh")
    sys.exit(1)
del mesh  # free memory

smooth1 = vtk.vtkSmoothPolyDataFilter()
smooth1.SetInputConnection(conn.GetOutputPort())
smooth1.SetNumberOfIterations(7)
smooth1.SetRelaxationFactor(0.2)
smooth1.FeatureEdgeSmoothingOff()
smooth1.BoundarySmoothingOff()
smooth1.Update()
del conn  # free memory

print('Decimating mesh  ', end='')
reduction = 1. - 1. / interpolation
decimate = vtk.vtkQuadricDecimation()
decimate.SetInputConnection(smooth1.GetOutputPort())
decimate.SetTargetReduction(reduction)
decimate.Update()
ncells = decimate.GetOutput().GetNumberOfCells()
if ncells > 0: print(" --> Remaining %d cells" % ncells)
else:
    print("\nERROR: zero cells in mesh")
    sys.exit(1)
del smooth1  # free memory

smooth2 = vtk.vtkSmoothPolyDataFilter()
smooth2.SetInputConnection(decimate.GetOutputPort())
smooth2.SetNumberOfIterations(7)
smooth2.SetRelaxationFactor(0.2)
smooth2.FeatureEdgeSmoothingOff()
    def CreateSurface(self):
        _ = i18n.InstallLanguage(self.language)

        reader = vtk.vtkXMLImageDataReader()
        reader.SetFileName(self.filename)
        reader.Update()
        
        image = reader.GetOutput()
        
        if (self.flip_image):
            # Flip original vtkImageData
            flip = vtk.vtkImageFlip()
            flip.SetInput(reader.GetOutput())
            flip.SetFilteredAxis(1)
            flip.FlipAboutOriginOn()
            image = flip.GetOutput()
            
        # Create vtkPolyData from vtkImageData
        if self.mode == "CONTOUR":
            contour = vtk.vtkContourFilter()
            contour.SetInput(image)
            contour.SetValue(0, self.min_value) # initial threshold
            contour.SetValue(1, self.max_value) # final threshold
            contour.GetOutput().ReleaseDataFlagOn()
            contour.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = contour.GetOutput()
        else: #mode == "GRAYSCALE":
            mcubes = vtk.vtkMarchingCubes()
            mcubes.SetInput(image)
            mcubes.SetValue(0, 255)
            mcubes.ComputeScalarsOn()
            mcubes.ComputeGradientsOn()
            mcubes.ComputeNormalsOn()
            mcubes.ThresholdBetween(self.min_value, self.max_value)
            mcubes.GetOutput().ReleaseDataFlagOn()
            mcubes.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = mcubes.GetOutput()

        if self.decimate_reduction:
            decimation = vtk.vtkQuadricDecimation()
            decimation.SetInput(polydata)
            decimation.SetTargetReduction(self.decimate_reduction)
            decimation.GetOutput().ReleaseDataFlagOn()
            decimation.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = decimation.GetOutput()

        if self.smooth_iterations and self.smooth_relaxation_factor:
            smoother = vtk.vtkSmoothPolyDataFilter()
            smoother.SetInput(polydata)
            smoother.SetNumberOfIterations(self.smooth_iterations)
            smoother.SetFeatureAngle(80)
            smoother.SetRelaxationFactor(self.smooth_relaxation_factor)
            smoother.FeatureEdgeSmoothingOn()
            smoother.BoundarySmoothingOn()
            smoother.GetOutput().ReleaseDataFlagOn()
            smoother.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = smoother.GetOutput()


        if self.keep_largest:
            conn = vtk.vtkPolyDataConnectivityFilter()
            conn.SetInput(polydata)
            conn.SetExtractionModeToLargestRegion()
            conn.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = conn.GetOutput()

        # 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 self.fill_holes:
            filled_polydata = vtk.vtkFillHolesFilter()
            filled_polydata.SetInput(polydata)
            filled_polydata.SetHoleSize(300)
            filled_polydata.AddObserver("ProgressEvent", lambda obj,evt:
                    self.SendProgress(obj, _("Generating 3D surface...")))
            polydata = filled_polydata.GetOutput()



        filename = tempfile.mktemp()
        writer = vtk.vtkXMLPolyDataWriter()
        writer.SetInput(polydata)
        writer.SetFileName(filename)
        writer.Write()

        self.pipe.send(None)
        self.pipe.send(filename)
Exemple #27
0
tf = vtk.vtkTriangleFilter()
tf.SetInputConnection(ps.GetOutputPort())

attr = vtk.vtkRandomAttributeGenerator()
attr.SetInputConnection(tf.GetOutputPort())
attr.GeneratePointScalarsOn()
attr.SetMinimumComponentValue(-0.05)
attr.SetMaximumComponentValue(0.05)

# This jitters the geometry
warp = vtk.vtkWarpScalar()
warp.SetInputConnection(attr.GetOutputPort())
warp.SetScaleFactor(0.02)

# Decimator without volume constraint
deci = vtk.vtkQuadricDecimation()
deci.SetInputConnection(warp.GetOutputPort())
deci.SetTargetReduction(.95)
deci.AttributeErrorMetricOn()
deci.VolumePreservationOff()

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(warp.GetOutputPort())

actor = vtk.vtkActor()
actor.SetMapper(mapper)

# Decimator with volume constraint
deci2 = vtk.vtkQuadricDecimation()
deci2.SetInputConnection(warp.GetOutputPort())
deci2.SetTargetReduction(.95)
Exemple #28
0
def vtk_quadric_decimation(inputdata,
                           target_reduction=.9,
                           volume_preservation=False,
                           attribute_error_metric=False,
                           scalars_weight=.1,
                           vectors_weight=.1,
                           normals_weight=.1,
                           tcoords_weight=.1,
                           tensors_weight=.1,
                           verbose=False):
    """Wrapper for VTK QuadricDecimation

    Based on Garland and Heckbert (1997)
    See documentation: https://www.vtk.org/doc/nightly/html/classvtkQuadricDecimation.html#details

    Arguments:
        inputdata (vtk.vtkPolyData): vtk object containing vertices and simplices
        target_reduction (double): Desired reduction (expressed as a fraction of the original number of triangles) (default: .9).
        volume_preservation (bool): Decide whether to activate volume preservation which greatly reduces errors in triangle normal direction (default: False).
        attribute_error_metric (bool): Decide whether to include data attributes in the error metric. If False, the attribute weights will be ignored (default False).

        scalars_weight (double): (default .1).
        vectors_weight (double): (default .1).
        normals_weight (double): (default .1).
        tcoords_weight (double): (default .1).
        tensors_weight (double): (default .1).

        If a weight is set to None, it will be deactivated.

        verbose (bool): Print out steps and basic statistics (default False).

    Returns:
        decimatedPoly: vtkPolyData object
    """

    title_string = 'VTK Quadric Decimation'

    if not isinstance(inputdata, vtkPolyData):
        raise TypeError(
            'Unknown dtype for inputdata! vtk.vtkPolyData expected.')

    inputPoly = vtkPolyData()
    inputPoly.ShallowCopy(inputdata)

    decimate = vtkQuadricDecimation()
    decimate.SetInputData(inputPoly)

    # set parameters
    decimate.SetTargetReduction(target_reduction)
    decimate.SetVolumePreservation(volume_preservation)
    decimate.SetAttributeErrorMetric(attribute_error_metric)

    if scalars_weight != None:
        decimate.SetScalarsAttribute(True)
        decimate.SetScalarsWeight(scalars_weight)
    else:
        decimate.SetScalarsAttribute(False)

    if vectors_weight != None:
        decimate.SetVectorsAttribute(True)
        decimate.SetVectorsWeight(vectors_weight)
    else:
        decimate.SetVectorsAttribute(False)

    if normals_weight != None:
        decimate.SetNormalsAttribute(True)
        decimate.SetNormalsWeight(normals_weight)
    else:
        decimate.SetNormalsAttribute(False)

    if tcoords_weight != None:
        decimate.SetTCoordsAttribute(True)
        decimate.SetTCoordsWeight(tcoords_weight)
    else:
        decimate.SetTCoordsAttribute(False)

    if tensors_weight != None:
        decimate.SetTensorsAttribute(True)
        decimate.SetTensorsWeight(tensors_weight)
    else:
        decimate.SetTensorsAttribute(False)

    # execute
    decimate.Update()

    decimatedPoly = vtkPolyData()
    decimatedPoly.ShallowCopy(decimate.GetOutput())

    if verbose:
        print_decimation_result(title_string, inputPoly, decimatedPoly,
                                ('target_reduction=' + str(target_reduction)))

    return decimatedPoly
Exemple #29
0
    def AddNewActor(self, slice_, mask, surface_parameters):
        """
        Create surface actor, save into project and send it to viewer.
        """
        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[:3]

        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 range(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 range(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'])

            mesh = cy_mesh.Mesh(polydata)
            cy_mesh.ca_smoothing(mesh, options['angle'],
                                 options['max distance'],
                                 options['min weight'], options['steps'])
            #  polydata = mesh.to_vtk()

            #  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.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

        to_measure = polydata

        # If InVesalius is running without GUI
        if wx.GetApp() is None:
            proj = prj.Project()
            #Create Surface instance
            if overwrite:
                surface = Surface(index=self.last_surface_index)
                proj.ChangeSurface(surface)
            else:
                surface = Surface(name=surface_name)
                index = proj.AddSurface(surface)
                surface.index = index
                self.last_surface_index = index
            surface.colour = colour
            surface.polydata = polydata

        # With GUI
        else:
            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()

            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=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',
                                      actor=old_actor)

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

            Publisher.sendMessage('Update surface info in GUI',
                                  surface=surface)

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

            Publisher.sendMessage('End busy cursor')
            del actor
def volume_to_polydata(volume,
                       origin=(0, 0, 0),
                       num_simplify_iter=0,
                       smooth=False,
                       level=0.):

    vol = volume > level

    # vol_padded = np.zeros(vol.shape+(10,10,10), np.bool)
    # vol_padded[5:-5, 5:-5, 5:-5] = vol
    vol_padded = np.pad(
        vol, ((5, 5), (5, 5), (5, 5)), 'constant'
    )  # need this otherwise the sides of volume will not close and expose the hollow inside of structures

    t = time.time()
    vs, fs = mcubes.marching_cubes(
        vol_padded, 0
    )  # more than 5 times faster than skimage.marching_cube + correct_orientation
    sys.stderr.write('marching cube: %.2f seconds\n' % (time.time() - t))

    # t = time.time()
    # vs, faces = marching_cubes(vol_padded, 0) # y,x,z
    # sys.stderr.write('marching cube: %.2f seconds\n' % (time.time() - t))

    # t = time.time()
    # fs = correct_mesh_orientation(vol_padded, vs, faces)
    # sys.stderr.write('correct orientation: %.2f seconds\n' % (time.time() - t))

    vs = vs[:, [1, 0, 2]] + origin - (5, 5, 5)
    # vs = vs[:, [1,0,2]] + origin

    # t = time.time()
    # area = mesh_surface_area(vs, fs)
    # # print 'area: %.2f' % area
    # sys.stderr.write('compute surface area: %.2f seconds\n' % (time.time() - t)) #

    t = time.time()

    polydata = mesh_to_polydata(vs, fs)

    sys.stderr.write('mesh_to_polydata: %.2f seconds\n' % (time.time() - t))  #

    for simplify_iter in range(num_simplify_iter):

        t = time.time()

        deci = vtk.vtkQuadricDecimation()
        deci.SetInputData(polydata)

        deci.SetTargetReduction(0.8)
        # 0.8 means each iteration causes the point number to drop to 20% the original

        deci.Update()

        polydata = deci.GetOutput()

        if smooth:

            smoother = vtk.vtkWindowedSincPolyDataFilter()
            #         smoother.NormalizeCoordinatesOn()
            smoother.SetPassBand(.1)
            smoother.SetNumberOfIterations(20)
            smoother.SetInputData(polydata)
            smoother.Update()

            polydata = smoother.GetOutput()

        n_pts = polydata.GetNumberOfPoints()

        if polydata.GetNumberOfPoints() < 200:
            break

        sys.stderr.write('simplify %d @ %d: %.2f seconds\n' %
                         (simplify_iter, n_pts, time.time() - t))  #

    return polydata
def quadric_decimation(data,ratio):
    sim = vtk.vtkQuadricDecimation();
    sim.SetTargetReduction(ratio);
    sim.SetInputData(data);
    sim.Update()
    return sim.GetOutput();
Exemple #32
0
pl3d.SetQFileName("" + str(VTK_DATA_ROOT) + "/Data/combq.bin")
pl3d.SetScalarFunctionNumber(100)
pl3d.SetVectorFunctionNumber(202)
pl3d.Update()
pl3d_output = pl3d.GetOutput().GetBlock(0)
gf = vtk.vtkGeometryFilter()
gf.SetInputData(pl3d_output)
tf = vtk.vtkTriangleFilter()
tf.SetInputConnection(gf.GetOutputPort())
gMapper = vtk.vtkPolyDataMapper()
gMapper.SetInputConnection(gf.GetOutputPort())
gMapper.SetScalarRange(pl3d_output.GetScalarRange())
gActor = vtk.vtkActor()
gActor.SetMapper(gMapper)
# Don't look at attributes
mesh = vtk.vtkQuadricDecimation()
mesh.SetInputConnection(tf.GetOutputPort())
mesh.SetTargetReduction(.90)
mesh.AttributeErrorMetricOn()
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(mesh.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# This time worry about attributes
mesh2 = vtk.vtkQuadricDecimation()
mesh2.SetInputConnection(tf.GetOutputPort())
mesh2.SetTargetReduction(.90)
mesh2.AttributeErrorMetricOff()
mapper2 = vtk.vtkPolyDataMapper()
mapper2.SetInputConnection(mesh2.GetOutputPort())
actor2 = vtk.vtkActor()
tf = vtk.vtkTriangleFilter()
tf.SetInputConnection(ps.GetOutputPort())

attr = vtk.vtkRandomAttributeGenerator()
attr.SetInputConnection(tf.GetOutputPort())
attr.GeneratePointScalarsOn()
attr.SetMinimumComponentValue(-0.05)
attr.SetMaximumComponentValue(0.05)

# This jitters the geometry
warp = vtk.vtkWarpScalar()
warp.SetInputConnection(attr.GetOutputPort())
warp.SetScaleFactor(0.02)

# Decimator without volume constraint
deci = vtk.vtkQuadricDecimation()
deci.SetInputConnection(warp.GetOutputPort())
deci.SetTargetReduction(.95)
deci.AttributeErrorMetricOn()
deci.VolumePreservationOff()

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(warp.GetOutputPort())

actor = vtk.vtkActor()
actor.SetMapper(mapper)

# Decimator with volume constraint
deci2 = vtk.vtkQuadricDecimation()
deci2.SetInputConnection(warp.GetOutputPort())
deci2.SetTargetReduction(.95)
Exemple #34
0
    def Decimate(self,
                 target_reduction,
                 volume_preservation=False,
                 attribute_error=False,
                 scalars=True,
                 vectors=True,
                 normals=False,
                 tcoords=True,
                 tensors=True,
                 scalars_weight=0.1,
                 vectors_weight=0.1,
                 normals_weight=0.1,
                 tcoords_weight=0.1,
                 tensors_weight=0.1,
                 inplace=True):
        """
        Reduces the number of triangles in a triangular mesh using
        vtkQuadricDecimation.

        Parameters
        ----------
        mesh : vtk.PolyData
            Mesh to decimate

        target_reduction : float
            Fraction of the original mesh to remove.
            TargetReduction is set to 0.9, this filter will try to reduce
            the data set to 10% of its original size and will remove 90%
            of the input triangles.

        volume_preservation : bool, optional
            Decide whether to activate volume preservation which greatly reduces
            errors in triangle normal direction. If off, volume preservation is
            disabled and if AttributeErrorMetric is active, these errors can be
            large. Defaults to False.

        attribute_error : bool, optional
            Decide whether to include data attributes in the error metric. If
            off, then only geometric error is used to control the decimation.
            Defaults to False.

        scalars : bool, optional
            If attribute errors are to be included in the metric (i.e.,
            AttributeErrorMetric is on), then the following flags control which
            attributes are to be included in the error calculation. Defaults to
            True.

        vectors : bool, optional
            See scalars parameter. Defaults to True.

        normals : bool, optional
            See scalars parameter. Defaults to False.

        tcoords : bool, optional
            See scalars parameter. Defaults to True.

        tensors : bool, optional
            See scalars parameter. Defaults to True.

        scalars_weight : float, optional
            The scaling weight contribution of the scalar attribute. These
            values are used to weight the contribution of the attributes towards
            the error metric. Defaults to 0.1.

        vectors_weight : float, optional
            See scalars weight parameter. Defaults to 0.1.

        normals_weight : float, optional
            See scalars weight parameter. Defaults to 0.1.

        tcoords_weight : float, optional
            See scalars weight parameter. Defaults to 0.1.

        tensors_weight : float, optional
            See scalars weight parameter. Defaults to 0.1.

        inplace : bool, optional
            Updates mesh in-place while returning nothing.

        Returns
        -------
        outmesh : vtkInterface.PolyData
            Decimated mesh.  None when inplace=True.

        """
        # create decimation filter
        decimate = vtk.vtkQuadricDecimation()  # vtkDecimatePro as well

        decimate.SetVolumePreservation(volume_preservation)
        decimate.SetAttributeErrorMetric(attribute_error)
        decimate.SetScalarsAttribute(scalars)
        decimate.SetVectorsAttribute(vectors)
        decimate.SetNormalsAttribute(normals)
        decimate.SetTCoordsAttribute(tcoords)
        decimate.SetTensorsAttribute(tensors)
        decimate.SetScalarsWeight(scalars_weight)
        decimate.SetVectorsWeight(vectors_weight)
        decimate.SetNormalsWeight(normals_weight)
        decimate.SetTCoordsWeight(tcoords_weight)
        decimate.SetTensorsWeight(tensors_weight)
        decimate.SetTargetReduction(target_reduction)

        decimate.SetInputData(self)
        decimate.Update()

        if inplace:
            self.Overwrite(decimate.GetOutput())
        else:
            return PolyData(decimate.GetOutput())
Exemple #35
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.AddInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(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.SetInput(to_measure)
        volume =  float(measured_polydata.GetVolume())
        surface.volume = volume
        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.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
def join_process_surface(filenames, algorithm, smooth_iterations, smooth_relaxation_factor, decimate_reduction, keep_largest, fill_holes, options, msg_queue):
    def send_message(msg):
        try:
            msg_queue.put_nowait(msg)
        except queue.Full as e:
            print(e)

    log_path = tempfile.mktemp('vtkoutput.txt')
    fow = vtk.vtkFileOutputWindow()
    fow.SetFileName(log_path)
    ow = vtk.vtkOutputWindow()
    ow.SetInstance(fow)

    send_message('Joining surfaces ...')
    polydata_append = vtk.vtkAppendPolyData()
    for f in filenames:
        reader = vtk.vtkXMLPolyDataReader()
        reader.SetFileName(f)
        reader.Update()

        polydata = reader.GetOutput()

        polydata_append.AddInputData(polydata)
        del reader
        del polydata

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

    send_message('Cleaning surface ...')
    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

    if algorithm == 'ca_smoothing':
        send_message('Calculating normals ...')
        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'])

        send_message('Context Aware smoothing ...')
        mesh = cy_mesh.Mesh(polydata)
        cy_mesh.ca_smoothing(mesh, options['angle'],
                             options['max distance'],
                             options['min weight'],
                             options['steps'])
        #  polydata = mesh.to_vtk()

        #  polydata.SetSource(None)
        #  polydata.DebugOn()
    #  else:
        #  #smoother = vtk.vtkWindowedSincPolyDataFilter()
        #  send_message('Smoothing ...')
        #  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 not decimate_reduction:
        print("Decimating", decimate_reduction)
        send_message('Decimating ...')
        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.Register(None)
    #  to_measure.SetSource(None)

    if keep_largest:
        send_message('Finding the 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:
        send_message('Filling 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

    to_measure = 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.SplittingOn()
    normals.AutoOrientNormalsOn()
    normals.NonManifoldTraversalOn()
    normals.ComputeCellNormalsOn()
    #  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

    send_message('Calculating area and volume ...')
    measured_polydata = vtk.vtkMassProperties()
    measured_polydata.SetInputData(to_measure)
    measured_polydata.Update()
    volume =  float(measured_polydata.GetVolume())
    area =  float(measured_polydata.GetSurfaceArea())
    del measured_polydata

    filename = tempfile.mktemp(suffix='_full.vtp')
    writer = vtk.vtkXMLPolyDataWriter()
    writer.SetInputData(polydata)
    writer.SetFileName(filename)
    writer.Write()
    del writer

    print("MY PID", os.getpid())
    return filename, {'volume': volume, 'area': area}
Exemple #37
0
def join_process_surface(filenames, algorithm, smooth_iterations,
                         smooth_relaxation_factor, decimate_reduction,
                         keep_largest, fill_holes, options, msg_queue):
    def send_message(msg):
        try:
            msg_queue.put_nowait(msg)
        except queue.Full as e:
            print(e)

    send_message('Joining surfaces ...')
    polydata_append = vtk.vtkAppendPolyData()
    for f in filenames:
        reader = vtk.vtkXMLPolyDataReader()
        reader.SetFileName(f)
        reader.Update()

        polydata = reader.GetOutput()

        polydata_append.AddInputData(polydata)
        del reader
        del polydata

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

    send_message('Cleaning surface ...')
    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

    if algorithm == 'ca_smoothing':
        send_message('Calculating normals ...')
        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'])

        send_message('Context Aware smoothing ...')
        mesh = cy_mesh.Mesh(polydata)
        cy_mesh.ca_smoothing(mesh, options['angle'], options['max distance'],
                             options['min weight'], options['steps'])
        #  polydata = mesh.to_vtk()

        #  polydata.SetSource(None)
        #  polydata.DebugOn()
    else:
        #smoother = vtk.vtkWindowedSincPolyDataFilter()
        send_message('Smoothing ...')
        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)
        send_message('Decimating ...')
        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.Register(None)
    #  to_measure.SetSource(None)

    if keep_largest:
        send_message('Finding the 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:
        send_message('Filling 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

    to_measure = 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.SplittingOff()
    #  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

    send_message('Calculating area and volume ...')
    measured_polydata = vtk.vtkMassProperties()
    measured_polydata.SetInputData(to_measure)
    measured_polydata.Update()
    volume = float(measured_polydata.GetVolume())
    area = float(measured_polydata.GetSurfaceArea())
    del measured_polydata

    filename = tempfile.mktemp(suffix='_full.vtp')
    writer = vtk.vtkXMLPolyDataWriter()
    writer.SetInputData(polydata)
    writer.SetFileName(filename)
    writer.Write()
    del writer

    print("MY PID", os.getpid())
    return filename, {'volume': volume, 'area': area}
Exemple #38
0
def decimation(vtk_poly_data, reduction=0.95, verbose=False):
    """
    Call of vtkQuadricDecimation on a vtk_poly_data to decimate the mesh

    Parameters
    ----------
    vtk_poly_data : vtkPolyData
        vtkPolyData is a data object that is a concrete implementation of
        vtkDataSet. vtkPolyData represents a geometric structure consisting
        of vertices, lines, polygons, and/or triangle strips.
        Point and cell attribute values (e.g., scalars, vectors, etc.)
        also are represented.

    reduction : float, optional
        Percentage of reduction for the decimation 0.95 will reduce the
        vtk_poly_date of 95%

    verbose : bool, optional
        If True, print for some information of each part of the algorithms

    Returns
    -------
    out : vtkPolyData
        vtkPolyData is a data object that is a concrete implementation of
        vtkDataSet. vtkPolyData represents a geometric structure consisting
        of vertices, lines, polygons, and/or triangle strips.
        Point and cell attribute values (e.g., scalars, vectors, etc.)
    """
    if verbose:

        print(("=" * 80 + "\n" + "Decimation : \n"
               "\tReduction (percentage) :{}\n"
               "\n"
               "\tBefore decimation\n"
               "\t-----------------\n"
               "\tThere are {} points.\n"
               "\tThere are {} polygons.\n").format(
                   reduction, vtk_poly_data.GetNumberOfPoints(),
                   vtk_poly_data.GetNumberOfPolys()))

    decimate = vtk.vtkQuadricDecimation()
    decimate.SetTargetReduction(reduction)

    if vtk.VTK_MAJOR_VERSION <= 5:
        decimate.SetInputConnection(vtk_poly_data.GetProducerPort())
        decimate.SetInput(vtk_poly_data)
    else:
        decimate.SetInputData(vtk_poly_data)

    decimate.Update()

    vtk_poly_decimated = vtk.vtkPolyData()
    vtk_poly_decimated.ShallowCopy(decimate.GetOutput())

    if verbose:
        print(("\tAfter decimation\n"
               "\t-----------------\n"
               "\tThere are {} points.\n"
               "\tThere are {} polygons.\n" + 80 * "=").format(
                   reduction, vtk_poly_data.GetNumberOfPoints(),
                   vtk_poly_data.GetNumberOfPolys()))

    return vtk_poly_decimated