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
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())
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
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()
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
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
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
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