예제 #1
0
def vmtksurfacecapper(surface,method='centerpoint',nrings=4,const=0.1, interactive=0):
    capper = vmtkscripts.vmtkSurfaceCapper()
    capper.Surface = surface
    capper.Method = method
    capper.NumberOfRings = nrings
    capper.ConstraintFactor = const
    capper.Interactive = interactive
    capper.Execute()
    return capper.Surface
예제 #2
0
def vmtksurfacecapper(surface, method='centerpoint', nrings=4, const=0.1):
    capper = vmtkscripts.vmtkSurfaceCapper()
    capper.Surface = surface
    capper.Method = method
    capper.NumberOfRings = nrings
    capper.ConstraintFactor = const
    capper.Interactive = 0
    capper.Execute()
    return capper.Surface
 def GetVolume(self):
     """Returns the volume of the vessel"""
     """
     capSurface=vtk.vtkFillHolesFilter()
     capSurface.SetInputData(self.Surface)
     capSurface.Update()"""
     capSurface = vmtkscripts.vmtkSurfaceCapper()
     capSurface.Interactive = 0
     capSurface.Surface = self.Surface
     capSurface.Execute()
     vesselVolume = vtk.vtkMassProperties()
     vesselVolume.SetInputData(capSurface.Surface)
     print("Vessel Volume:{}", vesselVolume.GetVolume())
예제 #4
0
파일: vmtklib.py 프로젝트: ajgeers/utils
def vmtksurfacecapper(surface):
    """Caps the holes of a surface.

    Args:
        surface: Surface mesh of vascular geometry with holes at inlets and
            outlets.

    Returns:
        Surface mesh with capped holes. Each cap has an ID assigned for easy
        specification of boundary conditions.
        Celldata:
            CellEntityIds: ID assigned to caps.

    """
    capper = vmtkscripts.vmtkSurfaceCapper()
    capper.Surface = surface
    capper.Method = 'centerpoint'
    capper.Interactive = 0
    capper.Execute()
    return capper.Surface
예제 #5
0
파일: vmtklib.py 프로젝트: sheep-z/utils
def vmtksurfacecapper(surface):
    """Caps the holes of a surface.

    Args:
        surface: Surface mesh of vascular geometry with holes at inlets and
            outlets.

    Returns:
        Surface mesh with capped holes. Each cap has an ID assigned for easy
        specification of boundary conditions.
        Celldata:
            CellEntityIds: ID assigned to caps.

    """
    capper = vmtkscripts.vmtkSurfaceCapper()
    capper.Surface = surface
    capper.Method = 'centerpoint'
    capper.Interactive = 0
    capper.Execute()
    return capper.Surface
예제 #6
0
def Execute(args):
    print("evaluate centerlines")
    
    reader_ctr = vmtkscripts.vmtkSurfaceReader()
    reader_ctr.InputFileName = args.centerlines
    reader_ctr.Execute()
    
    print(args.clean_ctr)
    if(args.clean_ctr):
        cleaner = vtk.vtkCleanPolyData()
        cleaner.PointMergingOn()
        cleaner.SetInputData(reader_ctr.Surface)
        cleaner.Update()
        centerlines = cleaner.GetOutput()
    else:
        centerlines = reader_ctr.Surface
    
    centerlines.BuildLinks()
    centerlines.BuildCells()
    
    # calculate length for each segment
    # seems to be some error in prevous calculation
    for i in range(centerlines.GetNumberOfCells()):
        cell = centerlines.GetCell(i)
        length_ = 0.0
        prevPoint = cell.GetPoints().GetPoint(0)
        for j in range(cell.GetNumberOfPoints()):
            point = cell.GetPoints().GetPoint(j)
            length_ += vtk.vtkMath.Distance2BetweenPoints(prevPoint,point)**0.5
            prevPoint = point
        centerlines.GetCellData().GetArray("length").SetTuple(i, [length_])
        
    #writer2 = vmtkscripts.vmtkSurfaceWriter()
    #writer2.OutputFileName = "centerlines_test.vtp"
    #writer2.Input = centerlines
    #writer2.Execute()
    
    
    reader_br = vmtkscripts.vmtkSurfaceReader()
    reader_br.InputFileName = args.surface
    reader_br.Execute()
    
    #if (reader_br.Surface.GetPointData().GetNormals() == None):
        #normalsFilter = vmtkscripts.vmtkSurfaceNormals()
        #normalsFilter.ComputeCellNormals = 1
        #normalsFilter.Surface = reader_br.Surface
        #normalsFilter.NormalsArrayName = 'Normals'
        #normalsFilter.Execute()
        #surface_reference = normalsFilter.Surface
    #else:
    surface_reference = reader_br.Surface
        
    
    locator_surf = vtk.vtkPointLocator()
    locator_surf.SetDataSet(surface_reference)
    locator_surf.BuildLocator()
    
    locator_cell = vtk.vtkCellLocator()
    locator_cell.SetDataSet(surface_reference)
    locator_cell.BuildLocator()

    
    cell_Ids = vtk.vtkIdList()
    outputLines = vtk.vtkCellArray()
    output = vtk.vtkPolyData()
    
    triangles = vtk.vtkCellArray()
    triangle_pd = vtk.vtkPolyData()
    triangle_pts = vtk.vtkPoints()
    
    lengthArray = vtk.vtkDoubleArray()
    lengthArray.SetName("length")
    lengthArray.SetNumberOfComponents(1)
    
    pts_ids = vtk.vtkIdList()
    factor = 1.0
    factor2 = 2.0
    pd_count = 0
    
    size_range = [0.0, 0.0]
    
    mid_points = vtk.vtkPoints()
    vertex = vtk.vtkCellArray()
    
    bifurcation_info = {}
    for i in range(centerlines.GetNumberOfCells()):
        bifurcation_info[i] = {"clip_id": [], "cell_pt_id": [], "mid_pt": [], "step":[], "less_length": 0.0}
        cell = centerlines.GetCell(i)
        if cell.GetCellType() not in (vtk.VTK_POLY_LINE, vtk.VTK_LINE):
             continue

        n_cell_pts = cell.GetNumberOfPoints()
        
        start_end_pt = [0, n_cell_pts-1]
        cell_length_half = centerlines.GetCellData().GetArray("length").GetTuple(i)[0]/2.0
        
        for j in start_end_pt:
            pt_id_pd = cell.GetPointIds().GetId(j)
            
            centerlines.GetPointCells(pt_id_pd, cell_Ids)
            if (cell_Ids.GetNumberOfIds() > 1):
                radius = centerlines.GetPointData().GetArray("MaximumInscribedSphereRadius").GetTuple(pt_id_pd)[0]
                length = 0.0
                radius2 = 0.0
                prev_point = centerlines.GetPoint(pt_id_pd)
                if( j == start_end_pt[0]):
                    step = 1
                    stop = start_end_pt[-1]
                else:
                    step = -1
                    stop = -1
                for k in range(j, stop, step):
                    point = centerlines.GetPoint(cell.GetPointIds().GetId(k))
                    length += vtk.vtkMath.Distance2BetweenPoints(prev_point,point)**0.5
                    prev_point = point
                    if (length > (factor*radius + factor2*radius2)):
                        #print(length)
                        pl_vec = centerlines.GetPointData().GetArray("FrenetTangent").GetTuple(cell.GetPointIds().GetId(k))
                        pl = vtk.vtkPlane()
                        pl.SetOrigin(point)
                        pl.SetNormal(pl_vec)
        
                        cut = vtk.vtkCutter()
                        cut.SetInputData(surface_reference)
                        cut.SetCutFunction(pl)
                        cut.Update()

                        ex = vtk.vtkPolyDataConnectivityFilter()
                        ex.SetInputConnection(cut.GetOutputPort())
                        #ex.SetExtractionModeToAllRegions()
                        ex.SetExtractionModeToClosestPointRegion()
                        ex.SetClosestPoint(point)
                        ex.Update()
                        
                        lp = ex.GetOutput()
                        close_cell(lp)

                        cutStrips = vtk.vtkStripper()  # Forms loops (closed polylines) from cutter
                        cutStrips.SetInputData(lp)
                        cutStrips.Update()
                        cutPoly = vtk.vtkPolyData()  # This trick defines polygons as polyline loop
                        cutPoly.SetPoints((cutStrips.GetOutput()).GetPoints())
                        cutPoly.SetPolys((cutStrips.GetOutput()).GetLines())
                        
                        area_test = ComputePolygonArea(cutPoly)
                        size_ratio = area_test/(np.pi*radius**2)
                        #print(area_test, radius, size_ratio)
                        
                        #writerline = vmtkscripts.vmtkSurfaceWriter()
                        #writerline.OutputFileName = "test_loop_{0}.vtp".format(pd_count)
                        #writerline.Input = cutPoly #ex.GetOutput()
                        #writerline.Execute()
                        #pd_count += 1
                        if (length < cell_length_half):
                            if(size_ratio > 2.0  ):
                                continue
                            
                            cv, offset, shape = ComputeBranchSectionShape(cutPoly, point)
                            
                            if(cv > 0.2): # standard deviation / mean 
                                continue
                            if(offset > 0.10): # centroid of slice vs centerline point
                                continue
                        #if(shape > 0.8):
                         #   continue
                        
                        #writerline = vmtkscripts.vmtkSurfaceWriter()
                        #writerline.OutputFileName = "test_loop_{0}.vtp".format(pd_count)
                        #writerline.Input = cutPoly #ex.GetOutput()
                        #writerline.Execute()
                        #pd_count += 1
                            
                        #print(length)
                        clip_id = cell.GetPointIds().GetId(k)
                        bifurcation_info[i]["clip_id"].append(clip_id)
                        bifurcation_info[i]["cell_pt_id"].append(k)
                        bifurcation_info[i]["step"].append(step)
                        bifurcation_info[i]["less_length"] += length
                        tmp_idx = k 
                        break
                    
                midway_length = 0.0
                
                prev_point = centerlines.GetPoint(pt_id_pd)
                print("hello")
                for k in range(tmp_idx, stop, step):
                    if k == 1198:
                        print(k)
                    point = centerlines.GetPoint(cell.GetPointIds().GetId(k))
                    midway_length += vtk.vtkMath.Distance2BetweenPoints(prev_point, point)**0.5
                    prev_point = point
                    if (midway_length >= cell_length_half):
                        bifurcation_info[i]["mid_pt"].append(point)
                        pt_id = mid_points.InsertNextPoint(point)
                        vertex.InsertNextCell(1, [pt_id])
                        mid_idx = k
                        break

    
    mid_point_pd = vtk.vtkPolyData()
    mid_point_pd.SetPoints(mid_points)
    mid_point_pd.SetVerts(vertex)
    
    writerline = vmtkscripts.vmtkSurfaceWriter()
    writerline.OutputFileName = "test_vertex_{0}.vtp".format(0)

    writerline.Input = mid_point_pd
    writerline.Execute()
    
                    
        #return

    tree = vtk.vtkModifiedBSPTree()
    tree.SetDataSet(surface_reference)
    tree.BuildLocator()

    #t = [ 1 for i in bifurcation_info.keys() if len(bifurcation_info[i]) == 2]
    two_bif = False
    pd_count = 0

    avg_x_area = vtk.vtkDoubleArray()
    avg_x_area.SetName("avg_crosssection")
    avg_x_area.SetNumberOfComponents(1)
    avg_x_area.SetNumberOfTuples(centerlines.GetNumberOfCells())
    avg_x_area.Fill(-1.0)
    
    aspect_ratio = vtk.vtkDoubleArray()
    aspect_ratio.SetName("aspect_ratio")
    aspect_ratio.SetNumberOfComponents(1)
    aspect_ratio.SetNumberOfTuples(centerlines.GetNumberOfCells())
    aspect_ratio.Fill(-1.0)
    
    vol_array = vtk.vtkDoubleArray()
    vol_array.SetName("volume")
    vol_array.SetNumberOfComponents(1)
    vol_array.SetNumberOfTuples(centerlines.GetNumberOfCells())
    vol_array.Fill(-1.0)
    
    len_array = vtk.vtkDoubleArray()
    len_array.SetName("length_wo_bifurcation")
    len_array.SetNumberOfComponents(1)
    len_array.SetNumberOfTuples(centerlines.GetNumberOfCells())
    len_array.Fill(-1.0)
    
    append = vtk.vtkAppendPolyData()
    
    for cell_id in bifurcation_info:
        id_sorted = sorted(bifurcation_info[cell_id]["cell_pt_id"])
        step_direction = [x for _,x in sorted(zip(bifurcation_info[cell_id]["cell_pt_id"], bifurcation_info[cell_id]["step"]))]
        #print(step_direction)
        
        if (len(bifurcation_info[cell_id]["cell_pt_id"]) < 2):
            two_bif = False
        else:
            two_bif = True
            diff = bifurcation_info[cell_id]["cell_pt_id"][0] - bifurcation_info[cell_id]["cell_pt_id"][1]
            if(abs(diff) < 2): # there is a problem if there less than two points
                print("houston we got a problem")
                
        if (not two_bif):
            
            clip_id = centerlines.GetCell(cell_id).GetPointIds().GetId(id_sorted[0])
            clip_id_m1 = centerlines.GetCell(cell_id).GetPointIds().GetId(id_sorted[0]+step_direction[0])
            start_pt = centerlines.GetPoint(clip_id)
            surface_pt_id = locator_surf.FindClosestPoint(start_pt)
        
            # vector from pt(start_pt+1) - pt(start_pt) 
            v_start = [ x - y for x,y in zip(centerlines.GetPoint(clip_id_m1), start_pt)]
            v_ctr_start = centerlines.GetPointData().GetArray("FrenetTangent").GetTuple(clip_id)
            v_normal_start = centerlines.GetPointData().GetArray("FrenetNormal").GetTuple(clip_id)
            
       
            # want inward facing normals
            if (vtk.vtkMath.Dot(v_start, v_ctr_start) < 0.0):
                v_ctr_start = [-1.0*x for x in v_ctr_start]

            #print(clip_tangent)
            plane1 = vtk.vtkPlane()
            plane1.SetOrigin(start_pt)
            plane1.SetNormal(v_ctr_start)
            
            seamFilter = vtkvmtk.vtkvmtkTopologicalSeamFilter()
            seamFilter.SetInputData(surface_reference)
            seamFilter.SetClosestPoint(surface_reference.GetPoint(surface_pt_id))
            seamFilter.SetSeamScalarsArrayName("SeamScalars")
            seamFilter.SetSeamFunction(plane1)

            clipper = vtk.vtkClipPolyData()
            clipper.SetInputConnection(seamFilter.GetOutputPort())
            clipper.GenerateClipScalarsOff()
            clipper.GenerateClippedOutputOn()

            connectivity = vtk.vtkPolyDataConnectivityFilter()
            connectivity.SetInputConnection(clipper.GetOutputPort())
            connectivity.SetExtractionModeToClosestPointRegion()
            
            surface_mid_pt = locator_surf.FindClosestPoint(bifurcation_info[cell_id]["mid_pt"][0])
            connectivity.SetClosestPoint(surface_reference.GetPoint(surface_mid_pt))

            surfaceCleaner = vtk.vtkCleanPolyData()
            surfaceCleaner.SetInputConnection(connectivity.GetOutputPort())
            surfaceCleaner.Update()

            surfaceTriangulator = vtk.vtkTriangleFilter()
            surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort())
            surfaceTriangulator.PassLinesOff()
            surfaceTriangulator.PassVertsOff()
            surfaceTriangulator.Update()
            
            capper = vmtkscripts.vmtkSurfaceCapper()
            capper.Surface = surfaceTriangulator.GetOutput()
            capper.Method = "simple"
            capper.Interactive = 0
            capper.Execute()
            
            get_prop = vtk.vtkMassProperties()
            get_prop.SetInputData(capper.Surface)
            get_prop.Update()
            
            volume = get_prop.GetVolume()
            new_length = centerlines.GetCellData().GetArray("length").GetTuple(cell_id)[0] - bifurcation_info[cell_id]["less_length"]
            average_area = volume/new_length
            
            avg_x_area.SetTuple(cell_id, [average_area])
            aspect_ratio.SetTuple(cell_id, [average_area/new_length])
            vol_array.SetTuple(cell_id, [volume])
            len_array.SetTuple(cell_id, [new_length])
            
            
            append.AddInputData(capper.Surface)
            append.Update()
            #print(new_length, centerlines.GetCellData().GetArray("length").GetTuple(cell_id)[0], bifurcation_info[cell_id]["less_length"])


            #pd_count += 1
    
    writerline = vmtkscripts.vmtkSurfaceWriter()
    writerline.OutputFileName = args.out_file
    writerline.Input = append.GetOutput()
    writerline.Execute()

    #print( bifurcation_info)
    centerlines.GetCellData().AddArray(avg_x_area)
    centerlines.GetCellData().AddArray(aspect_ratio)
    centerlines.GetCellData().AddArray(vol_array)
    centerlines.GetCellData().AddArray(len_array)
    
    writer = vmtkscripts.vmtkSurfaceWriter()
    writer.OutputFileName = args.out_segments
    writer.Input = centerlines
    writer.Execute()
예제 #7
0
    def Execute(self):

        from vmtk import vmtkscripts
        if self.Surface == None:
            self.PrintError('Error: No input surface.')

        wallEntityOffset = 1

        if self.SkipCapping or not self.BoundaryLayerOnCaps:
            self.PrintLog("Not capping surface")
            surface = self.Surface
            cellEntityIdsArray = vtk.vtkIntArray()
            cellEntityIdsArray.SetName(self.CellEntityIdsArrayName)
            cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells())
            cellEntityIdsArray.FillComponent(0,0.0)
            surface.GetCellData().AddArray(cellEntityIdsArray)
        else:
            self.PrintLog("Capping surface")
            capper = vmtkscripts.vmtkSurfaceCapper()
            capper.Surface = self.Surface
            capper.Interactive = 0
            capper.Method = self.CappingMethod
            capper.TriangleOutput = 0
            capper.CellEntityIdOffset = wallEntityOffset
            capper.Execute()
            surface = capper.Surface

        if self.SkipRemeshing:
            remeshedSurface = surface
        else:
            self.PrintLog("Remeshing surface")
            remeshing = vmtkscripts.vmtkSurfaceRemeshing()
            remeshing.Surface = surface
            remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            remeshing.TargetEdgeLength = self.TargetEdgeLength
            remeshing.MaxEdgeLength = self.MaxEdgeLength
            remeshing.MinEdgeLength = self.MinEdgeLength
            remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor
            remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
            remeshing.TriangleSplitFactor = self.TriangleSplitFactor
            remeshing.ElementSizeMode = self.ElementSizeMode
            if self.RemeshCapsOnly:
                remeshing.ExcludeEntityIds = [wallEntityOffset]
            remeshing.Execute()
            remeshedSurface = remeshing.Surface

        if self.BoundaryLayer:

            projection = vmtkscripts.vmtkSurfaceProjection()
            projection.Surface = remeshedSurface
            projection.ReferenceSurface = surface
            projection.Execute()

            normals = vmtkscripts.vmtkSurfaceNormals()
            normals.Surface = projection.Surface
            normals.NormalsArrayName = 'Normals'
            normals.Execute()

            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = normals.Surface
            surfaceToMesh.Execute()

            self.PrintLog("Generating boundary layer")
            placeholderCellEntityId = 9999
            boundaryLayer = vmtkscripts.vmtkBoundaryLayer()
            boundaryLayer.Mesh = surfaceToMesh.Mesh
            boundaryLayer.WarpVectorsArrayName = 'Normals'
            boundaryLayer.NegateWarpVectors = True
            boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName
            if self.ElementSizeMode == 'edgelength':
                boundaryLayer.ConstantThickness = True
            else:
                boundaryLayer.ConstantThickness = False
            boundaryLayer.IncludeSurfaceCells = 0
            boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers
            boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps
            boundaryLayer.Relaxation = self.Relaxation
            boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor
            boundaryLayer.SubLayerRatio = self.SubLayerRatio
            boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength
            boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor
            boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength
            if not self.BoundaryLayerOnCaps:
                boundaryLayer.SidewallCellEntityId = placeholderCellEntityId
                boundaryLayer.InnerSurfaceCellEntityId = wallEntityOffset
            boundaryLayer.Execute()

            meshToSurface = vmtkscripts.vmtkMeshToSurface()
            meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh
            meshToSurface.Execute()

            innerSurface = meshToSurface.Surface

            if not self.BoundaryLayerOnCaps:

                self.PrintLog("Capping inner surface")
                capper = vmtkscripts.vmtkSurfaceCapper()
                capper.Surface = innerSurface
                capper.Interactive = 0
                capper.Method = self.CappingMethod
                capper.TriangleOutput = 1
                capper.CellEntityIdOffset = wallEntityOffset
                capper.Execute()

                self.PrintLog("Remeshing endcaps")
                remeshing = vmtkscripts.vmtkSurfaceRemeshing()
                remeshing.Surface = capper.Surface
                remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
                remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor
                remeshing.MaxEdgeLength = self.MaxEdgeLength
                remeshing.MinEdgeLength = self.MinEdgeLength
                remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor
                remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
                remeshing.TriangleSplitFactor = self.TriangleSplitFactor
                remeshing.ElementSizeMode = self.ElementSizeMode
                remeshing.ExcludeEntityIds = [wallEntityOffset]
                remeshing.Execute()

                innerSurface = remeshing.Surface

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(innerSurface)
            sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh2.Surface = sizingFunction.GetOutput()
            surfaceToMesh2.Execute()
            
            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh2.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 0
            tetgen.OutputVolumeElements = 1
            tetgen.Execute()

            #w = vtk.vtkXMLUnstructuredGridWriter()
            #w.SetInput(tetgen.Mesh)
            #w.SetFileName('tet.vtu')
            #w.Write()

            if tetgen.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0:
                self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh and boundary layer.')

            if not self.BoundaryLayerOnCaps:
                surfaceToMesh.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName).FillComponent(0,wallEntityOffset)

            self.PrintLog("Assembling final mesh")
            appendFilter = vtkvmtk.vtkvmtkAppendFilter()
            appendFilter.AddInputData(surfaceToMesh.Mesh)
            appendFilter.AddInputData(boundaryLayer.Mesh)
            appendFilter.AddInputData(tetgen.Mesh)

            #appendFilter.AddInput(boundaryLayer.InnerSurfaceMesh)

            if not self.BoundaryLayerOnCaps:
                threshold = vtk.vtkThreshold()
                threshold.SetInputData(surfaceToMesh2.Mesh)
                threshold.ThresholdByUpper(1.5)
                threshold.SetInputArrayToProcess(0,0,0,1,self.CellEntityIdsArrayName)
                threshold.Update()
                endcaps = threshold.GetOutput()
                appendFilter.AddInputData(endcaps)

            appendFilter.Update()

            self.Mesh = appendFilter.GetOutput()

            if not self.BoundaryLayerOnCaps:
                cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName)

                def VisitNeighbors(i, cellEntityId):
                    cellPointIds = vtk.vtkIdList()
                    self.Mesh.GetCellPoints(i,cellPointIds)
                    neighborPointIds = vtk.vtkIdList()
                    neighborPointIds.SetNumberOfIds(1)
                    pointNeighborCellIds = vtk.vtkIdList()
                    neighborCellIds = vtk.vtkIdList()

                    for j in range(cellPointIds.GetNumberOfIds()):
                        neighborPointIds.SetId(0,cellPointIds.GetId(j))
                        self.Mesh.GetCellNeighbors(i,neighborPointIds,pointNeighborCellIds)
                        for k in range(pointNeighborCellIds.GetNumberOfIds()):
                            neighborCellIds.InsertNextId(pointNeighborCellIds.GetId(k))

                    for j in range(neighborCellIds.GetNumberOfIds()):
                        cellId = neighborCellIds.GetId(j)
                        neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId)
                        neighborCellType = self.Mesh.GetCellType(cellId)
                        if neighborCellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]:
                            continue
                        if neighborCellEntityId != placeholderCellEntityId:
                            continue
                        cellEntityIdsArray.SetTuple1(cellId,cellEntityId)
                        VisitNeighbors(cellId,cellEntityId)

                for i in range(self.Mesh.GetNumberOfCells()):
                    cellEntityId = cellEntityIdsArray.GetTuple1(i)
                    cellType = self.Mesh.GetCellType(i)
                    if cellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]:
                        continue
                    if cellEntityId in [0, 1, placeholderCellEntityId]:
                        continue
                    VisitNeighbors(i,cellEntityId)

        else:

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(remeshedSurface)
            sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            self.PrintLog("Converting surface to mesh")
            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = sizingFunction.GetOutput()
            surfaceToMesh.Execute()

            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 1
            tetgen.OutputVolumeElements = 1
            tetgen.Execute()

            self.Mesh = tetgen.Mesh

            if self.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0:
                self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh.')
                self.Mesh = surfaceToMesh.Mesh

        if self.Tetrahedralize:

            tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter()
            tetrahedralize.SetInputData(self.Mesh)
            tetrahedralize.Update()

            self.Mesh = tetrahedralize.GetOutput()

        self.RemeshedSurface = remeshedSurface
예제 #8
0
    def Execute(self):

        from vmtk import vmtkscripts
        if self.Surface == None:
            self.PrintError('Error: No input surface.')

        wallEntityOffset = 1

        if self.SkipCapping or not self.BoundaryLayerOnCaps:
            self.PrintLog("Not capping surface")
            surface = self.Surface
            cellEntityIdsArray = vtk.vtkIntArray()
            cellEntityIdsArray.SetName(self.CellEntityIdsArrayName)
            cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells())
            cellEntityIdsArray.FillComponent(0,0.0)
            surface.GetCellData().AddArray(cellEntityIdsArray)
        else:
            self.PrintLog("Capping surface")
            capper = vmtkscripts.vmtkSurfaceCapper()
            capper.Surface = self.Surface
            capper.Interactive = 0
            capper.Method = self.CappingMethod
            capper.TriangleOutput = 0
            capper.CellEntityIdOffset = wallEntityOffset
            capper.Execute()
            surface = capper.Surface

        if self.SkipRemeshing:
            remeshedSurface = surface
        else:
            self.PrintLog("Remeshing surface")
            remeshing = vmtkscripts.vmtkSurfaceRemeshing()
            remeshing.Surface = surface
            remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            remeshing.TargetEdgeLength = self.TargetEdgeLength
            remeshing.MaxEdgeLength = self.MaxEdgeLength
            remeshing.MinEdgeLength = self.MinEdgeLength
            remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor
            remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
            remeshing.TriangleSplitFactor = self.TriangleSplitFactor
            remeshing.ElementSizeMode = self.ElementSizeMode
            if self.RemeshCapsOnly:
                remeshing.ExcludeEntityIds = [wallEntityOffset]
            remeshing.Execute()
            remeshedSurface = remeshing.Surface



        if self.BoundaryLayer:

            projection = vmtkscripts.vmtkSurfaceProjection()
            projection.Surface = remeshedSurface
            projection.ReferenceSurface = surface
            projection.Execute()

            normals = vmtkscripts.vmtkSurfaceNormals()
            normals.Surface = projection.Surface
            normals.NormalsArrayName = 'Normals'
            normals.Execute()

            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = normals.Surface
            surfaceToMesh.Execute()

            self.PrintLog("Generating boundary layer fluid")
            placeholderCellEntityId = 9999
            boundaryLayer = vmtkscripts.vmtkBoundaryLayer()
            boundaryLayer.Mesh = surfaceToMesh.Mesh
            boundaryLayer.WarpVectorsArrayName = 'Normals'
            boundaryLayer.NegateWarpVectors = True
            boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName
            if self.ElementSizeMode == 'edgelength':
                boundaryLayer.ConstantThickness = True
            else:
                boundaryLayer.ConstantThickness = False
            boundaryLayer.IncludeSurfaceCells = 0
            boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers
            boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps
            boundaryLayer.Relaxation = self.Relaxation
            boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor
            boundaryLayer.SubLayerRatio = self.SubLayerRatio
            boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength
            boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor
            boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength
            if not self.BoundaryLayerOnCaps:
                boundaryLayer.SidewallCellEntityId     = placeholderCellEntityId
                boundaryLayer.InnerSurfaceCellEntityId = wallEntityOffset
                boundaryLayer.VolumeCellEntityId       = self.VolumeId_fluid
            boundaryLayer.Execute()



            self.PrintLog("Generating boundary layer solid")
            boundaryLayer2 = vmtkscripts.vmtkBoundaryLayer()
            boundaryLayer2.Mesh = surfaceToMesh.Mesh
            boundaryLayer2.WarpVectorsArrayName = 'Normals'
            boundaryLayer2.NegateWarpVectors = True
            boundaryLayer2.ThicknessArrayName = self.TargetEdgeLengthArrayName
            if self.ElementSizeMode == 'edgelength':
                boundaryLayer2.ConstantThickness = True
            else:
                boundaryLayer2.ConstantThickness = False
            boundaryLayer2.IncludeSurfaceCells = 1
            boundaryLayer2.NumberOfSubLayers = self.NumberOfSubLayers
            boundaryLayer2.NumberOfSubsteps = self.NumberOfSubsteps
            boundaryLayer2.Relaxation = self.Relaxation
            boundaryLayer2.LocalCorrectionFactor = self.LocalCorrectionFactor
            boundaryLayer2.SubLayerRatio = self.SubLayerRatio
            boundaryLayer2.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength
            boundaryLayer2.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor
            boundaryLayer2.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength
            if not self.BoundaryLayerOnCaps:
                boundaryLayer2.SidewallCellEntityId     = self.SolidSideWallId #placeholderCellEntityId
                boundaryLayer2.InnerSurfaceCellEntityId = self.InterfaceId_fsi # wallEntityOffset
                boundaryLayer2.OuterSurfaceCellEntityId = self.InterfaceId_outer # wallEntityOffset
                boundaryLayer2.VolumeCellEntityId       = self.VolumeId_solid
            boundaryLayer2.Execute()


            meshToSurface = vmtkscripts.vmtkMeshToSurface()
            meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh
            meshToSurface.Execute()

            innerSurface = meshToSurface.Surface


            if not self.BoundaryLayerOnCaps:

                self.PrintLog("Capping inner surface")
                capper = vmtkscripts.vmtkSurfaceCapper()
                capper.Surface = innerSurface
                capper.Interactive = 0
                capper.Method = self.CappingMethod
                capper.TriangleOutput = 1
                capper.CellEntityIdOffset = wallEntityOffset
                capper.Execute()

                self.PrintLog("Remeshing endcaps")
                remeshing = vmtkscripts.vmtkSurfaceRemeshing()
                remeshing.Surface = capper.Surface
                remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
                remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor
                remeshing.MaxEdgeLength = self.MaxEdgeLength
                remeshing.MinEdgeLength = self.MinEdgeLength
                remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor
                remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
                remeshing.TriangleSplitFactor = self.TriangleSplitFactor
                remeshing.ElementSizeMode = self.ElementSizeMode
                remeshing.ExcludeEntityIds = [wallEntityOffset] # [wallEntityOffset, InterfaceId] #[wallEntityOffset]
                remeshing.Execute()

                innerSurface = remeshing.Surface

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(innerSurface)
            sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh2.Surface = sizingFunction.GetOutput()
            surfaceToMesh2.Execute()

            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh2.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 1
            tetgen.OutputVolumeElements = 1
            tetgen.RegionAttrib = 0
            tetgen.Execute()

            ##### ADDING CELL IDs

            #array = vtk.vtkDoubleArray()
            #array.SetNumberOfTuples(tetgen.Mesh.GetNumberOfCells())
            #array.SetNumberOfComponents(1)
            #array.FillComponent(0, 1.0)
            #array.SetName('RegionIDs')
            #tetgen.Mesh.GetCellData().AddArray(array)

            #array = vtk.vtkDoubleArray()
            #array.SetNumberOfTuples(boundaryLayer.Mesh.GetNumberOfCells())
            #array.SetNumberOfComponents(1)
            #array.FillComponent(0, 1.0)
            #array.SetName('RegionIDs')
            #boundaryLayer.Mesh.GetCellData().AddArray(array)

            #array = vtk.vtkDoubleArray()
            #array.SetNumberOfTuples(boundaryLayer2.Mesh.GetNumberOfCells())
            #array.SetNumberOfComponents(1)
            #array.FillComponent(0, 2.0)
            #array.SetName('RegionIDs')
            #boundaryLayer2.Mesh.GetCellData().AddArray(array)

            #####

            # w1 = vtk.vtkXMLUnstructuredGridWriter()
            # w1.SetInputData(boundaryLayer2.Mesh)
            # w1.SetFileName('BoundaryLayer2.vtu')
            # w1.Write()
            #
            # w2 = vtk.vtkXMLUnstructuredGridWriter()
            # w2.SetInputData(tetgen.Mesh)
            # w2.SetFileName('Tetgen.vtu')
            # w2.Write()
            #
            # w3 = vtk.vtkXMLUnstructuredGridWriter()
            # w3.SetInputData(boundaryLayer.Mesh)
            # w3.SetFileName('BoundaryLayer.vtu')
            # w3.Write()
            #
            # w4 = vtk.vtkXMLUnstructuredGridWriter()
            # w4.SetInputData(boundaryLayer.InnerSurfaceMesh)
            # w4.SetFileName('InnerLayer.vtu')
            # w4.Write()

            #from IPython import embed; embed()

            self.PrintLog("Assembling fluid mesh")
            appendFilter = vtkvmtk.vtkvmtkAppendFilter()
            appendFilter.AddInputData(boundaryLayer.Mesh)
            appendFilter.AddInputData(tetgen.Mesh)
            appendFilter.Update()
            self.Mesh = appendFilter.GetOutput()

            if not self.BoundaryLayerOnCaps:
                cellEntityIdsArray = self.Mesh.GetCellData().GetArray(self.CellEntityIdsArrayName)

                def VisitNeighbors(i, cellEntityId):
                    cellPointIds = vtk.vtkIdList()
                    self.Mesh.GetCellPoints(i,cellPointIds)
                    neighborPointIds = vtk.vtkIdList()
                    neighborPointIds.SetNumberOfIds(1)
                    pointNeighborCellIds = vtk.vtkIdList()
                    neighborCellIds = vtk.vtkIdList()

                    for j in range(cellPointIds.GetNumberOfIds()):
                        neighborPointIds.SetId(0,cellPointIds.GetId(j))
                        self.Mesh.GetCellNeighbors(i,neighborPointIds,pointNeighborCellIds)
                        for k in range(pointNeighborCellIds.GetNumberOfIds()):
                            neighborCellIds.InsertNextId(pointNeighborCellIds.GetId(k))

                    for j in range(neighborCellIds.GetNumberOfIds()):
                        cellId = neighborCellIds.GetId(j)
                        neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId)
                        neighborCellType = self.Mesh.GetCellType(cellId)
                        if neighborCellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]:
                            continue
                        if neighborCellEntityId != placeholderCellEntityId:
                            continue
                        cellEntityIdsArray.SetTuple1(cellId,cellEntityId)
                        VisitNeighbors(cellId,cellEntityId)

                for i in range(self.Mesh.GetNumberOfCells()):
                    cellEntityId = cellEntityIdsArray.GetTuple1(i)
                    cellType = self.Mesh.GetCellType(i)
                    if cellType not in [vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE, vtk.VTK_QUAD]:
                        continue
                    if cellEntityId in [0, 1, placeholderCellEntityId]:
                        continue
                    VisitNeighbors(i,cellEntityId)


            self.PrintLog("Assembling final FSI mesh")
            appendFilter2 = vtkvmtk.vtkvmtkAppendFilter()
            appendFilter2.AddInputData(appendFilter.GetOutput())
            appendFilter2.AddInputData(boundaryLayer2.Mesh)
            appendFilter2.Update()
            self.Mesh = appendFilter2.GetOutput()


        else:

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(remeshedSurface)
            sizingFunction.SetSizingFunctionArrayName(self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            self.PrintLog("Converting surface to mesh")
            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = sizingFunction.GetOutput()
            surfaceToMesh.Execute()

            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 1
            tetgen.OutputVolumeElements = 1

            tetgen.Execute()

            self.Mesh = tetgen.Mesh

            if self.Mesh.GetNumberOfCells() == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0:
                self.PrintLog('An error occurred during tetrahedralization. Will only output surface mesh.')
                self.Mesh = surfaceToMesh.Mesh

        if self.Tetrahedralize:

            tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter()
            tetrahedralize.SetInputData(self.Mesh)
            tetrahedralize.Update()

            self.Mesh = tetrahedralize.GetOutput()

        self.RemeshedSurface = remeshedSurface
예제 #9
0
    def Execute(self):

        from vmtk import vmtkscripts
        if self.Surface == None:
            self.PrintError('Error: No input surface.')

        wallEntityOffset = 1

        if self.SkipCapping or not self.BoundaryLayerOnCaps:
            self.PrintLog("Not capping surface")
            surface = self.Surface
            cellEntityIdsArray = vtk.vtkIntArray()
            cellEntityIdsArray.SetName(self.CellEntityIdsArrayName)
            cellEntityIdsArray.SetNumberOfTuples(surface.GetNumberOfCells())
            cellEntityIdsArray.FillComponent(0, 0.0)
            surface.GetCellData().AddArray(cellEntityIdsArray)
        else:
            self.PrintLog("Capping surface")
            capper = vmtkscripts.vmtkSurfaceCapper()
            capper.Surface = self.Surface
            capper.Interactive = 0
            capper.Method = self.CappingMethod
            capper.TriangleOutput = 0
            capper.CellEntityIdOffset = self.Vessel_inlet_outlet
            capper.Execute()
            surface = capper.Surface

        if self.SkipRemeshing:
            remeshedSurface = surface
        else:
            self.PrintLog("Remeshing surface")
            remeshing = vmtkscripts.vmtkSurfaceRemeshing()
            remeshing.Surface = surface
            remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            remeshing.TargetEdgeLength = self.TargetEdgeLength
            remeshing.MaxEdgeLength = self.MaxEdgeLength
            remeshing.MinEdgeLength = self.MinEdgeLength
            remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor
            remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
            remeshing.TriangleSplitFactor = self.TriangleSplitFactor
            remeshing.ElementSizeMode = self.ElementSizeMode
            if self.RemeshCapsOnly:
                remeshing.ExcludeEntityIds = [self.Vessel_wall]
            remeshing.Execute()
            remeshedSurface = remeshing.Surface

        if self.BoundaryLayer:

            projection = vmtkscripts.vmtkSurfaceProjection()
            projection.Surface = remeshedSurface
            projection.ReferenceSurface = surface
            projection.Execute()

            normals = vmtkscripts.vmtkSurfaceNormals()
            normals.Surface = projection.Surface
            normals.NormalsArrayName = 'Normals'
            normals.Execute()

            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = normals.Surface
            surfaceToMesh.Execute()

            self.PrintLog("Generating 1st boundary layer -- PVS")
            placeholderCellEntityId = 9999
            boundaryLayer = vmtkscripts.vmtkBoundaryLayer()
            boundaryLayer.Mesh = surfaceToMesh.Mesh
            boundaryLayer.WarpVectorsArrayName = 'Normals'
            boundaryLayer.NegateWarpVectors = True
            boundaryLayer.ThicknessArrayName = self.TargetEdgeLengthArrayName
            if self.ElementSizeMode == 'edgelength':
                boundaryLayer.ConstantThickness = True
            else:
                boundaryLayer.ConstantThickness = False
            boundaryLayer.IncludeSurfaceCells = 0
            boundaryLayer.NumberOfSubLayers = self.NumberOfSubLayers
            boundaryLayer.NumberOfSubsteps = self.NumberOfSubsteps
            boundaryLayer.Relaxation = self.Relaxation
            boundaryLayer.LocalCorrectionFactor = self.LocalCorrectionFactor
            boundaryLayer.SubLayerRatio = self.SubLayerRatio
            boundaryLayer.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength
            boundaryLayer.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor
            boundaryLayer.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength
            if not self.BoundaryLayerOnCaps:
                boundaryLayer.SidewallCellEntityId = placeholderCellEntityId
                boundaryLayer.InnerSurfaceCellEntityId = self.Vessel_wall
                boundaryLayer.VolumeCellEntityId = self.PVS
            boundaryLayer.Execute()

            # We need a second boundary layer to make sure we have the right OuterSurface
            self.PrintLog("Generating 2nd boundary layer -- PVS")
            placeholderCellEntityId2 = 99999
            boundaryLayer2 = vmtkscripts.vmtkBoundaryLayer()
            boundaryLayer2.Mesh = surfaceToMesh.Mesh
            boundaryLayer2.WarpVectorsArrayName = 'Normals'
            boundaryLayer2.NegateWarpVectors = True
            boundaryLayer2.ThicknessArrayName = self.TargetEdgeLengthArrayName
            if self.ElementSizeMode == 'edgelength':
                boundaryLayer2.ConstantThickness = True
            else:
                boundaryLayer2.ConstantThickness = False
            boundaryLayer2.IncludeSurfaceCells = 1
            boundaryLayer2.NumberOfSubLayers = self.NumberOfSubLayers
            boundaryLayer2.NumberOfSubsteps = self.NumberOfSubsteps
            boundaryLayer2.Relaxation = self.Relaxation
            boundaryLayer2.LocalCorrectionFactor = self.LocalCorrectionFactor
            boundaryLayer2.SubLayerRatio = self.SubLayerRatio
            boundaryLayer2.Thickness = self.BoundaryLayerThicknessFactor * self.TargetEdgeLength
            boundaryLayer2.ThicknessRatio = self.BoundaryLayerThicknessFactor * self.TargetEdgeLengthFactor
            boundaryLayer2.MaximumThickness = self.BoundaryLayerThicknessFactor * self.MaxEdgeLength
            if not self.BoundaryLayerOnCaps:
                boundaryLayer2.SidewallCellEntityId = placeholderCellEntityId2
                boundaryLayer2.OuterSurfaceCellEntityId = self.PVS_wall
                boundaryLayer2.VolumeCellEntityId = self.PVS
            boundaryLayer2.Execute()

            meshToSurface = vmtkscripts.vmtkMeshToSurface()
            meshToSurface.Mesh = boundaryLayer.InnerSurfaceMesh
            meshToSurface.Execute()

            innerSurface = meshToSurface.Surface

            if not self.BoundaryLayerOnCaps:

                self.PrintLog("Capping inner surface")
                capper = vmtkscripts.vmtkSurfaceCapper()
                capper.Surface = innerSurface
                capper.Interactive = 0
                capper.Method = self.CappingMethod
                capper.TriangleOutput = 1
                capper.CellEntityIdOffset = self.Vessel_inlet_outlet
                capper.Execute()

                self.PrintLog("Remeshing endcaps")
                remeshing = vmtkscripts.vmtkSurfaceRemeshing()
                remeshing.Surface = capper.Surface
                remeshing.CellEntityIdsArrayName = self.CellEntityIdsArrayName
                remeshing.TargetEdgeLength = self.TargetEdgeLength * self.EndcapsEdgeLengthFactor
                remeshing.MaxEdgeLength = self.MaxEdgeLength
                remeshing.MinEdgeLength = self.MinEdgeLength
                remeshing.TargetEdgeLengthFactor = self.TargetEdgeLengthFactor * self.EndcapsEdgeLengthFactor
                remeshing.TargetEdgeLengthArrayName = self.TargetEdgeLengthArrayName
                remeshing.TriangleSplitFactor = self.TriangleSplitFactor
                remeshing.ElementSizeMode = self.ElementSizeMode
                remeshing.ExcludeEntityIds = [self.Vessel_wall]
                remeshing.Execute()

                innerSurface = remeshing.Surface

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(innerSurface)
            sizingFunction.SetSizingFunctionArrayName(
                self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            surfaceToMesh2 = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh2.Surface = sizingFunction.GetOutput()
            surfaceToMesh2.Execute()

            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh2.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 1
            tetgen.OutputVolumeElements = 1
            tetgen.RegionAttrib = 1
            tetgen.Execute()

            # Define VisitNeighbors used to differenciate markers in Sidewall areas
            def VisitNeighbors(i, cellEntityId, cellEntityIdsArray,
                               placeholderTag):
                cellPointIds = vtk.vtkIdList()
                self.Mesh.GetCellPoints(i, cellPointIds)
                neighborPointIds = vtk.vtkIdList()
                neighborPointIds.SetNumberOfIds(1)
                pointNeighborCellIds = vtk.vtkIdList()
                neighborCellIds = vtk.vtkIdList()

                for j in range(cellPointIds.GetNumberOfIds()):
                    neighborPointIds.SetId(0, cellPointIds.GetId(j))
                    self.Mesh.GetCellNeighbors(i, neighborPointIds,
                                               pointNeighborCellIds)
                    for k in range(pointNeighborCellIds.GetNumberOfIds()):
                        neighborCellIds.InsertNextId(
                            pointNeighborCellIds.GetId(k))

                for j in range(neighborCellIds.GetNumberOfIds()):
                    cellId = neighborCellIds.GetId(j)
                    neighborCellEntityId = cellEntityIdsArray.GetTuple1(cellId)
                    neighborCellType = self.Mesh.GetCellType(cellId)
                    if neighborCellType not in [
                            vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE,
                            vtk.VTK_QUAD
                    ]:
                        continue
                    if neighborCellEntityId != placeholderTag:
                        continue
                    cellEntityIdsArray.SetTuple1(cellId, cellEntityId)
                    VisitNeighbors(cellId, cellEntityId, cellEntityIdsArray,
                                   placeholderTag)

            self.PrintLog("Assembling PVS mesh - 1st layer")
            appendFilter = vtkvmtk.vtkvmtkAppendFilter()
            appendFilter.AddInputData(boundaryLayer.Mesh)
            appendFilter.AddInputData(tetgen.Mesh)
            appendFilter.Update()
            self.Mesh = appendFilter.GetOutput()

            # Use placeholderCellEntityId - inlet/outlet for the PVS-1
            if not self.BoundaryLayerOnCaps:
                cellEntityIdsArray = self.Mesh.GetCellData().GetArray(
                    self.CellEntityIdsArrayName)

                for i in range(self.Mesh.GetNumberOfCells()):
                    cellEntityId = cellEntityIdsArray.GetTuple1(i)
                    cellType = self.Mesh.GetCellType(i)
                    if cellType not in [
                            vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE,
                            vtk.VTK_QUAD
                    ]:
                        continue
                    if cellEntityId in [
                            0, 1, placeholderCellEntityId, self.Vessel_wall
                    ]:
                        continue
                    VisitNeighbors(
                        i, cellEntityId + self.PVS_inlet_outlet -
                        self.Vessel_inlet_outlet, cellEntityIdsArray,
                        placeholderCellEntityId)

            appendFilter.Update()
            self.Mesh = appendFilter.GetOutput()
            self.PrintLog("Assembling PVS mesh - 2nd layer")
            appendFilter2 = vtkvmtk.vtkvmtkAppendFilter()
            appendFilter2.AddInputData(appendFilter.GetOutput())
            appendFilter2.AddInputData(boundaryLayer2.Mesh)
            appendFilter2.Update()
            self.Mesh = appendFilter2.GetOutput()

            # Use placeholderCellEntityId2 - inlet/outlet for the PVS-2
            if not self.BoundaryLayerOnCaps:
                cellEntityIdsArray = self.Mesh.GetCellData().GetArray(
                    self.CellEntityIdsArrayName)

                for i in range(self.Mesh.GetNumberOfCells()):
                    cellEntityId = cellEntityIdsArray.GetTuple1(i)
                    cellType = self.Mesh.GetCellType(i)
                    if cellType not in [
                            vtk.VTK_TRIANGLE, vtk.VTK_QUADRATIC_TRIANGLE,
                            vtk.VTK_QUAD
                    ]:
                        continue
                    if cellEntityId in [
                            0, 1, placeholderCellEntityId2, self.Vessel_wall
                    ]:
                        continue
                    VisitNeighbors(i, cellEntityId, cellEntityIdsArray,
                                   placeholderCellEntityId2)

            self.PrintLog("Assembling final mesh")
            appendFilter2.Update()
            self.Mesh = appendFilter2.GetOutput()
        else:

            self.PrintLog("Computing sizing function")
            sizingFunction = vtkvmtk.vtkvmtkPolyDataSizingFunction()
            sizingFunction.SetInputData(remeshedSurface)
            sizingFunction.SetSizingFunctionArrayName(
                self.SizingFunctionArrayName)
            sizingFunction.SetScaleFactor(self.VolumeElementScaleFactor)
            sizingFunction.Update()

            self.PrintLog("Converting surface to mesh")
            surfaceToMesh = vmtkscripts.vmtkSurfaceToMesh()
            surfaceToMesh.Surface = sizingFunction.GetOutput()
            surfaceToMesh.Execute()

            self.PrintLog("Generating volume mesh")
            tetgen = vmtkscripts.vmtkTetGen()
            tetgen.Mesh = surfaceToMesh.Mesh
            tetgen.GenerateCaps = 0
            tetgen.UseSizingFunction = 1
            tetgen.SizingFunctionArrayName = self.SizingFunctionArrayName
            tetgen.CellEntityIdsArrayName = self.CellEntityIdsArrayName
            tetgen.Order = 1
            tetgen.Quality = 1
            tetgen.PLC = 1
            tetgen.NoBoundarySplit = 1
            tetgen.RemoveSliver = 1
            tetgen.OutputSurfaceElements = 1
            tetgen.OutputVolumeElements = 1

            tetgen.Execute()

            self.Mesh = tetgen.Mesh

            if self.Mesh.GetNumberOfCells(
            ) == 0 and surfaceToMesh.Mesh.GetNumberOfCells() > 0:
                self.PrintLog(
                    'An error occurred during tetrahedralization. Will only output surface mesh.'
                )
                self.Mesh = surfaceToMesh.Mesh

        if self.Tetrahedralize:

            tetrahedralize = vtkvmtk.vtkvmtkUnstructuredGridTetraFilter()
            tetrahedralize.SetInputData(self.Mesh)
            tetrahedralize.Update()

            self.Mesh = tetrahedralize.GetOutput()

        self.RemeshedSurface = remeshedSurface
예제 #10
0
def Execute(args):
    print("evaluate centerlines")
    
    # read centerlines
    reader_ctr = vmtkscripts.vmtkSurfaceReader()
    reader_ctr.InputFileName = args.centerlines
    reader_ctr.Execute()
    
    print(args.clean_ctr)
    if(args.clean_ctr):
        cleaner = vtk.vtkCleanPolyData()
        cleaner.PointMergingOn()
        cleaner.SetInputData(reader_ctr.Surface)
        cleaner.Update()
        centerlines = cleaner.GetOutput()
    else:
        centerlines = reader_ctr.Surface
    
    centerlines.BuildLinks()
    centerlines.BuildCells()
    
    # calculate length for each segment
    # seems to be some error in prevous calculation
    for i in range(centerlines.GetNumberOfCells()):
        cell = centerlines.GetCell(i)
        length_ = 0.0
        prevPoint = cell.GetPoints().GetPoint(0)
        for j in range(cell.GetNumberOfPoints()):
            point = cell.GetPoints().GetPoint(j)
            length_ += vtk.vtkMath.Distance2BetweenPoints(prevPoint,point)**0.5
            prevPoint = point
        centerlines.GetCellData().GetArray("length").SetTuple(i, [length_])
        
    #writer2 = vmtkscripts.vmtkSurfaceWriter()
    #writer2.OutputFileName = "centerlines_test.vtp"
    #writer2.Input = centerlines
    #writer2.Execute()
    
    #read clipped surface
    reader_br = vmtkscripts.vmtkSurfaceReader()
    reader_br.InputFileName = args.surface
    reader_br.Execute()
    
    #if (reader_br.Surface.GetPointData().GetNormals() == None):
        #normalsFilter = vmtkscripts.vmtkSurfaceNormals()
        #normalsFilter.ComputeCellNormals = 1
        #normalsFilter.Surface = reader_br.Surface
        #normalsFilter.NormalsArrayName = 'Normals'
        #normalsFilter.Execute()
        #surface_reference = normalsFilter.Surface
    #else:
    surface_reference = reader_br.Surface
   
    
    locator_surf = vtk.vtkPointLocator()
    locator_surf.SetDataSet(surface_reference)
    locator_surf.BuildLocator()
    
    locator_cell = vtk.vtkCellLocator()
    locator_cell.SetDataSet(surface_reference)
    locator_cell.BuildLocator()

    ctr_locator_cell = vtk.vtkCellLocator()
    ctr_locator_cell.SetDataSet(centerlines)
    ctr_locator_cell.BuildLocator()

    # read boundary
    reader_br = vmtkscripts.vmtkSurfaceReader()
    reader_br.InputFileName = args.boundary
    reader_br.Execute()
    
    boundary_reference = reader_br.Surface
    
    N_bnds = boundary_reference.GetPoints().GetNumberOfPoints()
    closestPoint = [0.0,0.0,0.0] # the coordinates of the closest point will be returned here
    closestPointDist2 = vtk.reference(0) # the squared distance to the closest point will be returned here
    ccell = vtk.vtkGenericCell()
    ccellID = vtk.reference(0) # the cell id of the cell containing the closest point will be returned here
    subID = vtk.reference(0) # this is rarely used (in triangle strips only, I believe)
    #dist = []
    
    cell_list = []
    count = 0 
    cell_list_ids = vtk.vtkIdTypeArray() # have to load the Id;s into an array to makethem persistent
    # otherwise the same memory location is being referenced
    cell_list_ids.SetNumberOfComponents(1)
    for bnd_pt_id in range(N_bnds):
        bnd_point =  boundary_reference.GetPoints().GetPoint(bnd_pt_id)
        ctr_locator_cell.FindClosestPoint(bnd_point, closestPoint, ccell, ccellID, subID, closestPointDist2)
        cell_list_ids.InsertNextTuple([ccellID])
        #print("hey", test)
        #c_pt_id = centerlines
        #print(ccellID)
        n_cell_pts = ccell.GetNumberOfPoints()
        
        start_end_pt = [int(0), int(n_cell_pts-1)]
        
        for c_pt_id in start_end_pt:
            point_ctr = ccell.GetPoints().GetPoint(c_pt_id)
            dist = vtk.vtkMath.Distance2BetweenPoints(closestPoint, point_ctr)
            if ( dist < 1e-7):
                cell_list.append((ccell, c_pt_id, int(cell_list_ids.GetTuple(count)[0])))
            #print(bnd_pt_id, c_pt_id, dist)
    
        count += 1
            
    #print(cell_list)

    for cell, start_pt, cell_Id in cell_list:
        print(cell_Id)
        n_cell_pts = cell.GetNumberOfPoints()
        length = centerlines.GetCellData().GetArray("length").GetTuple(cell_Id)[0]
        
        #print(length)
        prev_point = cell.GetPoints().GetPoint(start_pt)
        #print(prev_point)
        
        if( start_pt == 0):
            step = 1
            stop = n_cell_pts-1
        else:
            step = -1
            stop = -1
            
        length_new = 0.0
        avg_radius = 0.0
        avg_radius_old = 0.0
        std_radius  = 0.0
        radius_squ_sum = 0.0
        z_score = 0.0
        count = 1
        mid_point = (0.0, 0.0, 0.0)
        for k in range(start_pt, stop, step):
            
            point = centerlines.GetPoint(cell.GetPointIds().GetId(k))
            length_new += vtk.vtkMath.Distance2BetweenPoints(prev_point, point)**0.5
            prev_point = point
            
            radius = centerlines.GetPointData().GetArray("MaximumInscribedSphereRadius").GetTuple(cell.GetPointIds().GetId(k))[0]
            
            radius_squ_sum += radius**2 # using alternate form of standard deviation
            avg_radius = avg_radius_old + (radius -  avg_radius_old) / count
            
            
            if (count > 1):
                std_radius = ((radius_squ_sum - count*(avg_radius)**2.0) / (count -1))**0.5
                z_score = (radius - avg_radius_old ) /  std_radius
                
            #print(length_new, avg_radius, std_radius)
            avg_radius_old = copy.deepcopy(avg_radius)         
            
            if (length_new > 0.5*length):
                ctr_mid_point = centerlines.GetPoint(cell.GetPointIds().GetId(k))

            if ( length_new < 0.8*length):
                continue
            
            #print(z_score)
            count += 1
            if ( (z_score > 2.0 and count > int(0.5*n_cell_pts)) or  (length_new > (length - avg_radius_old)) ):
                # within close proximity to bifurcation 
                # or a small branch is intersecting with a large branch
                # this theory is untested
                pl_vec = centerlines.GetPointData().GetArray("FrenetTangent").GetTuple(cell.GetPointIds().GetId(k))
                plane1 = vtk.vtkPlane()
                plane1.SetOrigin(point)
                plane1.SetNormal(pl_vec)
                
                seam_pt = locator_surf.FindClosestPoint(point)
                
                seamFilter = vtkvmtk.vtkvmtkTopologicalSeamFilter()
                seamFilter.SetInputData(surface_reference)
                seamFilter.SetClosestPoint(surface_reference.GetPoint(seam_pt))
                seamFilter.SetSeamScalarsArrayName("SeamScalars")
                seamFilter.SetSeamFunction(plane1)

                clipper = vtk.vtkClipPolyData()
                clipper.SetInputConnection(seamFilter.GetOutputPort())
                clipper.GenerateClipScalarsOff()
                clipper.GenerateClippedOutputOn()

                connectivity = vtk.vtkPolyDataConnectivityFilter()
                connectivity.SetInputConnection(clipper.GetOutputPort())
                connectivity.SetExtractionModeToClosestPointRegion()
                
                surface_mid_pt = locator_surf.FindClosestPoint(ctr_mid_point)
                connectivity.SetClosestPoint(surface_reference.GetPoint(surface_mid_pt))

                surfaceCleaner = vtk.vtkCleanPolyData()
                surfaceCleaner.SetInputConnection(connectivity.GetOutputPort())
                surfaceCleaner.Update()

                surfaceTriangulator = vtk.vtkTriangleFilter()
                surfaceTriangulator.SetInputConnection(surfaceCleaner.GetOutputPort())
                surfaceTriangulator.PassLinesOff()
                surfaceTriangulator.PassVertsOff()
                surfaceTriangulator.Update()
                
                capper = vmtkscripts.vmtkSurfaceCapper()
                capper.Surface = surfaceTriangulator.GetOutput()
                capper.Method = "simple"
                capper.Interactive = 0
                capper.Execute()
                
                get_prop = vtk.vtkMassProperties()
                get_prop.SetInputData(capper.Surface)
                get_prop.Update()
                
                volume = get_prop.GetVolume()
                #new_length = centerlines.GetCellData().GetArray("length").GetTuple(cell_id)[0] - bifurcation_info[cell_id]["less_length"]
                average_area = volume/length_new
                print(average_area)
                break