def Centerline_Extraction(path_reader, path_writer, coeff_smooth=0.001, nb_iterations=50): #READ THE SURFACE print(" ---> Reading Mesh Closed STL surface") myReader = vmtkscripts.vmtkSurfaceReader() myReader.InputFileName = path_reader myReader.Format = 'stl' myReader.Execute() print("---> Computing Centerline") myCenterline = vmtkscripts.vmtkCenterlines() myCenterline.Surface = myReader.Surface myCenterline.AppendEndPoints = 1 myCenterline.Resampling = 1 myCenterline.ResamplingStepLength = 0.2 myCenterline.Execute() myCenterlineSmoother = vmtkscripts.vmtkCenterlineSmoothing() myCenterlineSmoother.Centerlines = myCenterline.Centerlines myCenterlineSmoother.SmoothingFactor = coeff_smooth myCenterlineSmoother.NumberOfSmoothingIterations = nb_iterations myCenterlineSmoother.Execute() #WRITE TO STL FILE print(" ---> Writing results to VTP file ") myWriter = vmtkscripts.vmtkSurfaceWriter() myWriter.Surface = myCenterlineSmoother.Centerlines myWriter.OutputFileName = path_writer #myWriter.Format = 'vtp' myWriter.Execute()
def Read_and_Smooth(path_reader, path_writer, coeff_smooth=0.001, nb_iterations=50): #READ THE SURFACE print(" ---> Reading Marching-Cube surface") myReader = vmtkscripts.vmtkSurfaceReader() myReader.InputFileName = path_reader myReader.Format = 'stl' myReader.Execute() #SMOOTH THE SURFACE print(" ---> Smoothing surface with coeff {} and {} ierations".format( coeff_smooth, nb_iterations)) mySmoother = vmtkscripts.vmtkSurfaceSmoothing() mySmoother.Surface = myReader.Surface mySmoother.PassBand = coeff_smooth mySmoother.NumberOfIterations = nb_iterations mySmoother.Execute() #WRITE TO STL FILE print(" ---> Writing results to STL file ") myWriter = vmtkscripts.vmtkSurfaceWriter() myWriter.Surface = mySmoother.Surface myWriter.OutputFileName = path_writer myWriter.Format = 'stl' myWriter.Execute()
def Execute(args): reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = args.surface reader.Execute() Surface = reader.Surface # estimates surface area to estimate the point density cleaner = vtk.vtkCleanPolyData() cleaner.SetInputData(Surface) cleaner.Update() triangleFilter = vtk.vtkTriangleFilter() triangleFilter.SetInputConnection(cleaner.GetOutputPort()) triangleFilter.Update() massProps = vtk.vtkMassProperties() massProps.SetInputConnection(triangleFilter.GetOutputPort()) massProps.Update() print(massProps.GetSurfaceArea()) area = massProps.GetSurfaceArea() target_area = 3.0**0.5 / 4.0 * args.edge_length**2.0 print("target number of cells: {0}".format( area / target_area)) # A_total = N*(area_equilateral_triangle) print("target number of points: {0}".format( area / target_area / 2.0)) #in the limit of equilateral triangles ratio ,Ncells/Npoints = 2
def read(infile): """ Reads VMTK centerline file. Parameters ---------- ifile : str Path to input VMTK centerline file (.vtp format). Returns ------- centerline : dict Dictionary of arrays defining the centerline. """ # read surface print() centerlineReader = vmtkscripts.vmtkSurfaceReader() centerlineReader.InputFileName = infile centerlineReader.Execute() # numpy adaptor clNumpyAdaptor = vmtkscripts.vmtkCenterlinesToNumpy() clNumpyAdaptor.Centerlines = centerlineReader.Surface clNumpyAdaptor.ConvertCellToPoint = 1 clNumpyAdaptor.Execute() return clNumpyAdaptor.ArrayDict
def warp_surface(args): print("warp the surface ") reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = args.surface reader.Execute() Surface = reader.Surface boundaries = vtkvmtk.vtkvmtkPolyDataBoundaryExtractor() boundaries.SetInputData(Surface) boundaries.Update() boundaryReferenceSystems = vtkvmtk.vtkvmtkBoundaryReferenceSystems() boundaryReferenceSystems.SetInputData(Surface) boundaryReferenceSystems.SetBoundaryRadiusArrayName('BoundaryRadius') boundaryReferenceSystems.SetBoundaryNormalsArrayName('BoundaryNormals') boundaryReferenceSystems.SetPoint1ArrayName('Point1') boundaryReferenceSystems.SetPoint2ArrayName('Point2') boundaryReferenceSystems.Update() ReferenceSystems = boundaryReferenceSystems.GetOutput() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.file_out writer.Input = warp.GetOutput() writer.Execute()
def VTPCenterline_To_Numpy(path_reader): myReader = vmtkscripts.vmtkSurfaceReader() myReader.InputFileName = path_reader myReader.Execute() NumpyAdaptor = vmtkscripts.vmtkCenterlinesToNumpy() NumpyAdaptor.Centerlines = myReader.Surface NumpyAdaptor.Execute() numpyCenterlines = NumpyAdaptor.ArrayDict CENTERLINE = numpyCenterlines["Points"] return CENTERLINE
def Add_extension(path_reader, path_writer, extension_ratio=10, target_edge_length=0.7, nb_iterations=5): myReader = vmtkscripts.vmtkSurfaceReader() myReader.InputFileName = path_reader myReader.Format = 'stl' myReader.Execute() myCenterline = vmtkscripts.vmtkCenterlines() myCenterline.Surface = myReader.Surface myCenterline.SeedSelectorName = 'openprofiles' myCenterline.Execute() myExtension = vmtkscripts.vmtkFlowExtensions() myExtension.Surface = myReader.Surface myExtension.Centerlines = myCenterline.Centerlines myExtension.AdaptiveExtensionLength = 1 myExtension.AdaptiveExtensionRadius = 1 myExtension.ExtensionMode = "boundarynormal" myExtension.ExtensionRatio = extension_ratio myExtension.Interactive = 0 myExtension.Execute() mySmoother = vmtkscripts.vmtkSurfaceSmoothing() mySmoother.Surface = myExtension.Surface mySmoother.PassBand = 0.3 mySmoother.NumberOfIterations = 5 mySmoother.Execute() myRemesh = vmtkscripts.vmtkSurfaceRemeshing() myRemesh.Surface = mySmoother.Surface myRemesh.ElementSizeMode = 'edgelength' myRemesh.TargetEdgeLength = target_edge_length myRemesh.NumberOfIterations = nb_iterations myRemesh.Execute() myWriter = vmtkscripts.vmtkSurfaceWriter() myWriter.Surface = myRemesh.Surface myWriter.OutputFileName = path_writer myWriter.Format = 'stl' myWriter.Execute()
def compute(infile, outfile): """ Calls VMTK routine for centerline extraction. Parameters ---------- infile : string Path to input mesh with open inlet/outlets (.stl format). outfile : string Path to output centerline (.vtp format). Returns ------- None """ # read surface centerlineReader = vmtkscripts.vmtkSurfaceReader() centerlineReader.InputFileName = infile centerlineReader.Execute() # centerline centerline = vmtkscripts.vmtkCenterlines() centerline.Surface = centerlineReader.Surface centerline.SeedSelectorName = 'openprofiles' centerline.AppendEndPoints = 1 centerline.Execute() # extract branches branchExtractor = vmtkscripts.vmtkBranchExtractor() branchExtractor.Centerlines = centerline.Centerlines branchExtractor.Execute() # merge centerlines centerlineMerge = vmtkscripts.vmtkCenterlineMerge() centerlineMerge.Centerlines = branchExtractor.Centerlines centerlineMerge.Execute() # write surface centerlineWriter = vmtkscripts.vmtkSurfaceWriter() centerlineWriter.OutputFileName = outfile centerlineWriter.Surface = centerlineMerge.Centerlines centerlineWriter.Execute()
def vmtksurfacereader(path): """Read a polydata (surface or centerline) and store it in a vtkPolyData object. Args: path: Path to the polydata file. Returns: vtkPolyData object. Note: Reads several polydata formats: vtp, vtk, stl, ply, tec (tecplot), dat (tecplot) """ reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = path reader.Execute() return reader.Surface
def Execute(args): print("flip boundary region for flow extensions") flip_id = [int(i) for i in args.flip_ids.strip(" ").split(",")] print(flip_id) surface_reader = vmtkscripts.vmtkSurfaceReader() surface_reader.InputFileName = args.surface_file surface_reader.Execute() surf = surface_reader.Surface for i in flip_id: id_ = surf.GetCellData().GetArray("BoundaryRegion").GetTuple(i) print(id_) new = [(j + 1) % 2 for j in id_] print(new) surf.GetCellData().GetArray("BoundaryRegion").SetTuple(i, new) writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = surf writer.Execute()
def Surface_Remesh(path_reader, path_writer, target_edge_length=0.7, nb_iterations=10): myReader = vmtkscripts.vmtkSurfaceReader() myReader.InputFileName = path_reader myReader.Format = 'stl' myReader.Execute() myRemesh = vmtkscripts.vmtkSurfaceRemeshing() myRemesh.Surface = myReader.Surface myRemesh.ElementSizeMode = 'edgelength' myRemesh.TargetEdgeLength = target_edge_length myRemesh.NumberOfIterations = nb_iterations myRemesh.Execute() myWriter = vmtkscripts.vmtkSurfaceWriter() myWriter.Surface = myRemesh.Surface myWriter.OutputFileName = path_writer myWriter.Format = 'stl' myWriter.Execute()
def Execute(args): print("clip 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.ConvertPolysToLinesOff() cleaner.SetInputData(reader_ctr.Surface) cleaner.Update() centerlines = cleaner.GetOutput() else: centerlines = reader_ctr.Surface centerlines.BuildLinks() centerlines.BuildCells() reader_br = vmtkscripts.vmtkSurfaceReader() reader_br.InputFileName = args.boundary_file reader_br.Execute() boundary_reference = reader_br.Surface #print(pt1, pt2) #v = pt2 - pt1 #pt1 - pt2 #v_mag = np.linalg.norm(v) #n = v / v_mag #print("should be 1.0", np.linalg.norm(n), n) #https://en.wikipedia.org/wiki/Vector_projection # get starting point from centroid by projecting centroid onto normal direction #neck_projection = np.dot(neck_centroid-pt1, n)*n #neck_start_pt = pt1 + neck_projection new_ctr = vtk.vtkPolyData() new_ctr.DeepCopy(centerlines) locator = vtk.vtkPointLocator() locator.SetDataSet(new_ctr) locator.BuildLocator() cell_loc = vtk.vtkCellLocator() cell_loc.SetDataSet(new_ctr) cell_loc.BuildLocator() clip_ids = [] new_points = vtk.vtkPoints() new_cell_array = vtk.vtkCellArray() scalar = vtk.vtkIntArray() scalar.SetNumberOfComponents(1) scalar.SetNumberOfTuples(new_ctr.GetNumberOfPoints()) scalar.SetName("clipper") scalar.Fill(0) for i in range(boundary_reference.GetNumberOfPoints()): pt = boundary_reference.GetPoint(i) #B pt_b = np.array(pt) #print(pt) #ctr_ptId = locator.FindClosestPoint(pt) id_list = vtk.vtkIdList() locator.FindClosestNPoints(2, pt, id_list) ctr1 = np.array(new_ctr.GetPoint(id_list.GetId(0))) # A ctr2 = np.array(new_ctr.GetPoint(id_list.GetId(1))) #ctr3 = np.array(new_ctr.GetPoint(ctr_ptId + 1)) n_br = np.array(boundary_reference.GetPointData().GetArray( "BoundaryNormals").GetTuple(i)) n_s_2 = np.dot(pt_b - ctr2, n_br) n_s_1 = np.dot(pt_b - ctr1, n_br) if (n_s_1 < 0.0): proj_start = ctr2 start_id = id_list.GetId(0) elif (n_s_2 < 0.0): proj_start = ctr1 start_id = id_list.GetId(1) else: print("two closest points are on same side") #Get each vector normal to outlet n_ctr = np.array(new_ctr.GetPointData().GetArray( "FrenetTangent").GetTuple(start_id)) if (np.dot(n_br, n_ctr) < 0.0): n_ctr = -1.0 * n_ctr #outlet centroid projected onto centerline based on FrenetTangent proj_vec = np.dot(n_br, pt_b - proj_start) * n_ctr proj_end = proj_vec + proj_start two_closest = vtk.vtkIdList() locator.FindClosestNPoints(2, proj_end, two_closest) vec_closest = np.array(new_ctr.GetPoints().GetPoint( two_closest.GetId(0))) - proj_end point_furthest = proj_end - vec_closest new_ctr.GetPoints().SetPoint(two_closest.GetId(1), tuple(point_furthest)) #new_ctr.GetPoints().SetPoint(two_closest.GetId(0), proj_end_other) #new_ctr.GetPointData().GetArray("FrenetTangent").SetTuple(closest_to, tuple(n_br)) cell_id_list = vtk.vtkIdList() new_ctr.GetPointCells(two_closest.GetId(0), cell_id_list) print("haller") print(cell_id_list.GetNumberOfIds()) ctr_cell = new_ctr.GetCell(cell_id_list.GetId(0)) #print(ctr_cell) print(n_s) if (n_s < -np.finfo(float).eps): start = cell_id_match + 1 stop = ctr_cell.GetNumberOfPoints() step = int(1) else: start = cell_id_match - 1 stop = int(-1) step = int(-1) new_poly_line = vtk.vtkPolyLine() for k in range(start, stop, step): old_pt_id = ctr_cell.GetPointIds().GetId(k) scalar.SetTuple(old_pt_id, [1]) #new_pt_d = new_points.InsertNextPoint(new_ctr.GetPonts().GetPoint(old_pt_id) #new_poly_line.GetPointIds().InsertNextId(old_pt_id) new_ctr.GetPointData().AddArray(scalar) new_ctr.GetPointData().SetActiveScalars("clipper") pass_arrays = vtk.vtkPassArrays() pass_arrays.SetInputData(new_ctr) pass_arrays.UseFieldTypesOn() pass_arrays.AddArray(vtk.vtkDataObject.POINT, "clipper") pass_arrays.GetOutput().GetPointData().SetActiveScalars("clipper") pass_arrays.AddFieldType(vtk.vtkDataObject.POINT) pass_arrays.AddFieldType(vtk.vtkDataObject.CELL) pass_arrays.Update() clip = vtk.vtkClipPolyData() clip.SetValue(0.5) clip.SetInputConnection(pass_arrays.GetOutputPort()) clip.InsideOutOn() #clip.GetOutput().GetPointData().CopyScalarsOff() #clip.GetOutput().GetPointData().CopyVectorsOff() #clip.GetOutput().GetCellData().CopyScalarsOff() #clip.GetOutput().GetCellData().CopyVectorsOff() clip.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file if (args.clean_ctr): cleaner2 = vtk.vtkCleanPolyData() cleaner2.PointMergingOn() cleaner.ConvertPolysToLinesOff() cleaner2.SetInputConnection(clip.GetOutputPort()) cleaner2.Update() writer.Input = cleaner2.GetOutput() else: writer.Input = clip.GetOutput() writer.Execute()
def Execute(args): print("clip 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.ConvertPolysToLinesOff() cleaner.SetInputData(reader_ctr.Surface) cleaner.Update() centerlines = cleaner.GetOutput() else: centerlines = reader_ctr.Surface centerlines.BuildLinks() centerlines.BuildCells() reader_br = vmtkscripts.vmtkSurfaceReader() reader_br.InputFileName = args.boundary_file reader_br.Execute() boundary_reference = reader_br.Surface #print(pt1, pt2) #v = pt2 - pt1 #pt1 - pt2 #v_mag = np.linalg.norm(v) #n = v / v_mag #print("should be 1.0", np.linalg.norm(n), n) #https://en.wikipedia.org/wiki/Vector_projection # get starting point from centroid by projecting centroid onto normal direction #neck_projection = np.dot(neck_centroid-pt1, n)*n #neck_start_pt = pt1 + neck_projection new_ctr = vtk.vtkPolyData() new_ctr.DeepCopy(centerlines) locator = vtk.vtkPointLocator() locator.SetDataSet(new_ctr) locator.BuildLocator() clip_ids = [] for i in range(boundary_reference.GetNumberOfPoints()): pt = boundary_reference.GetPoint(i) #B pt_b = np.array(pt) #print(pt) ctr_ptId = locator.FindClosestPoint(pt) ctr1 = np.array(new_ctr.GetPoint(ctr_ptId)) # A ctr2 = np.array(new_ctr.GetPoint(ctr_ptId - 1)) ctr3 = np.array(new_ctr.GetPoint(ctr_ptId + 1)) vec_b = pt_b - ctr1 #Get each vector normal to outlet n_ctr = np.array(new_ctr.GetPointData().GetArray( "FrenetTangent").GetTuple(ctr_ptId)) n_br = np.array(boundary_reference.GetPointData().GetArray( "BoundaryNormals").GetTuple(i)) n_s = np.dot(n_ctr, n_br) if (n_s < 0.0): n_ctr *= -1.0 #print(n_s) #np.dot(n_br, vec_b), # n_dot_b = np.dot(n_ctr, vec_b) #print(n_dot_b, n_dot_b*n_ctr+ctr1) # outlet centroid projected onto centerline based on FrenetTangent projected_pt = n_dot_b * n_ctr + ctr1 # compare previous and next point vec_nm1 = ctr2 - projected_pt vec_np1 = ctr3 - projected_pt n_dot_nm1 = np.dot(n_ctr, vec_nm1) n_dot_np1 = np.dot(n_ctr, vec_np1) #print(n_dot_nm1, n_dot_np1) # one is always positive and one is always negative assert n_dot_nm1 / n_dot_np1 < 0.0 #index info n_out_idx = 0 if (n_dot_nm1 < 0.0 and n_dot_np1 > 0.0): n_out_idx = 1 #print("nm1 is opposite direction of outlet", mvidx) else: n_out_idx = -1 #print("nm1 is same direction of outlet", mvidx) # is projection vector in opposite direction of normal? if (n_dot_b < 0.0): # move closest point mvidx = ctr_ptId else: #move next outside point mvidx = ctr_ptId + n_out_idx #move point #print(ctr_ptId, mvidx, n_out_idx) new_ctr.GetPoints().SetPoint(mvidx, projected_pt) cell_ids_list = vtk.vtkIdList() new_ctr.GetPointCells(mvidx, cell_ids_list) if (cell_ids_list.GetNumberOfIds() > 1): print("something has gone wrong, this is a bifurcation point") else: cell = new_ctr.GetCell(cell_ids_list.GetId(0)) for i in range(cell.GetNumberOfPoints()): if (cell.GetPointIds().GetId(i) == mvidx): # cell_id, point_id, numberOfPoints clip_ids.append((cell_ids_list.GetId(0), i, cell.GetNumberOfPoints(), n_out_idx)) print(clip_ids) outputLines = vtk.vtkCellArray() output = vtk.vtkPolyData() lengthArray = vtk.vtkDoubleArray() lengthArray.SetName("length") lengthArray.SetNumberOfComponents(1) cell_Ids = vtk.vtkIdList() new_points = vtk.vtkPoints() points_list = [] for i in range(new_ctr.GetNumberOfCells()): cell = new_ctr.GetCell(i) if cell.GetCellType() not in (vtk.VTK_POLY_LINE, vtk.VTK_LINE): continue edge = [] cell_ends = [0, cell.GetNumberOfPoints() - 1] edge.append(cell.GetPointIds().GetId(cell_ends[0])) edge.append(cell.GetPointIds().GetId(cell_ends[1])) start_pt = [] for e, idx in zip(edge, cell_ends): new_ctr.GetPointCells(e, cell_Ids) start_pt.append((cell_Ids.GetNumberOfIds(), idx)) cell_bounds = [t[1] for t in clip_ids if t[0] == i] # get cell point bounds cell_max_idx = [i[1] for i in start_pt if i[0] == 1] start_pt.sort(key=lambda tup: tup[0]) print(start_pt, cell_bounds, cell_max_idx) if (len(cell_bounds) == 2): # starts and ends outside bnd = sorted(cell_bounds) elif (len(cell_bounds) == 0): #starts and ends inside bnd = cell_ends elif (len(cell_bounds) == 1): #one point inside and one outside bnds = sorted([cell_ends[0], cell_bounds[0], cell_ends[1]]) if (start_pt[0][0] == 1 and start_pt[0][1] != 0): #print("start out") bnd = bnds[:-1] elif (start_pt[0][0] == 1 and start_pt[0][1] == 0): bnd = bnds[1:] else: print("whoops") #print(bnd) #if (args.clean_ctr): cell_branch_pt = [] #cell_Ids = vtk.vtkIdList() for j in range(cell.GetNumberOfPoints()): new_ctr.GetPointCells(cell.GetPointIds().GetId(j), cell_Ids) if (cell_Ids.GetNumberOfIds() > 1 and j not in cell_ends): cell_branch_pt.append(j) #print(cell.GetPointIds().GetId(j)) for j in cell_branch_pt: bnd.append(j) bnd.sort() #print("yeay") #print(bnd) for j in range(len(bnd) - 1): start_ = bnd[j] end_ = bnd[j + 1] pts_ids = vtk.vtkIdList() length = 0.0 prevPoint = cell.GetPoints().GetPoint(0) for k in range(start_, end_ + 1): pt_id = cell.GetPointIds().GetId(k) pts_ids.InsertNextId(pt_id) point = cell.GetPoints().GetPoint(k) length += vtk.vtkMath.Distance2BetweenPoints(prevPoint, point)**0.5 if (pt_id not in points_list): points_list.append(pt_id) prevPoint = point lengthArray.InsertNextTuple([length]) new_polyline = addPolyLine(pts_ids) outputLines.InsertNextCell(new_polyline) #if(k == j): #boundary_reference output.SetPoints(new_ctr.GetPoints()) output.SetLines(outputLines) output.GetCellData().AddArray(lengthArray) for i in range(new_ctr.GetPointData().GetNumberOfArrays()): output.GetPointData().AddArray(new_ctr.GetPointData().GetArray(i)) writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file if (args.clean_ctr): cleaner2 = vtk.vtkCleanPolyData() cleaner2.PointMergingOn() cleaner.ConvertPolysToLinesOff() cleaner2.SetInputData(output) cleaner2.Update() writer.Input = cleaner2.GetOutput() else: writer.Input = output writer.Execute()
from vmtk import vmtkscripts import argparse parser = argparse.ArgumentParser() parser.add_argument("fname", help="Enter the path to the input surface file", type=str) args = parser.parse_args() fname = args.fname outputName = fname.split('.')[:-1] + ['.vtu'] outputName = ''.join(outputName) surfaceReader = vmtkscripts.vmtkSurfaceReader() surfaceReader.InputFileName = fname surfaceReader.Execute() surfaceRemeshing = vmtkscripts.vmtkSurfaceRemeshing() surfaceRemeshing.Surface = surfaceReader.Surface surfaceRemeshing.ElementSizeMode = 'edgelength' surfaceRemeshing.TargetEdgeLength = 5.0 surfaceRemeshing.Execute() meshGenerator = vmtkscripts.vmtkMeshGenerator() meshGenerator.Surface = surfaceRemeshing.Surface meshGenerator.TargetEdgeLength = 5.0 meshGenerator.Execute() meshViewer = vmtkscripts.vmtkMeshViewer() meshViewer.Mesh = meshGenerator.Mesh meshViewer.Execute() meshWriter = vmtkscripts.vmtkMeshWriter() meshWriter.Mesh = meshGenerator.Mesh
def Execute(self): print("Get Surface Boundaries") reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = self.InputFile reader.Execute() self.Surface = reader.Surface #vtkPolyData #Define variables used by the algorithm inpts = vtk.vtkPoints() inPolys = vtk.vtkCellArray() # ints of vtkIdType # newPts numPts, newId, cellId #Get input points, polys and set the up in the vtkPolyData mesh inpts = self.Surface.GetPoints() inPolys = self.Surface.GetPolys() self.mesh.SetPoints(inpts) self.mesh.SetPolys(inPolys) #Build Links in the mesh to be able to perform complex polydata processes self.mesh.BuildLinks() #Get the number of Polys for scalar allocation numPolys = self.Surface.GetNumberOfPolys() numPts = self.Surface.GetNumberOfPoints() #Check the input to make sure it is there if (numPolys < 1): raise RuntimeError("No Input") #Set up Region scalar for each surface self.NewScalars.SetNumberOfTuples(numPolys) #Set up Feature Edges for Boundary Edge Detection inputCopy = self.Surface.NewInstance() inputCopy.ShallowCopy(self.Surface) #Set the Data to hold onto given Point Markers inputCopy.GlobalReleaseDataFlagOff() self.boundaries.SetInputData(inputCopy) self.boundaries.BoundaryEdgesOff() #(self.BoundaryEdges) self.boundaries.ManifoldEdgesOff() #(self.ManifoldEdges) self.boundaries.NonManifoldEdgesOff() #(self.NonManifoldEdges) self.boundaries.FeatureEdgesOn() #(self.FeatureEdges) self.boundaries.SetFeatureAngle(self.FeatureAngle) #inputCopy.Delete() self.boundaries.Update() # Set the boundary lines self.BoundaryLines.DeepCopy(self.boundaries.GetOutput()) # Initialize the arrays to be used in the flood fills self.SetBoundaryArrays() print("Starting Boundary Face Separation") # Set Region value of each cell to be zero initially reg = 0 for cellId in range(numPolys): self.NewScalars.InsertValue(cellId, reg) #Go through each cell and perfrom region identification proces #print(numPolys) for cellId in range(numPolys): #if(cellId % 1000 == 0): #print(cellId) #Check to make sure the value of the region at self cellId hasn't been set if (self.NewScalars.GetValue(cellId) == 0): reg += 1 self.CheckCells.InsertNextId(cellId) #Call function to find all cells within certain region self.FindBoundaryRegion(reg, 1) #print("party") self.CheckCells.Reset() self.CheckCells2.Reset() self.CheckCellsCareful.Reset() self.CheckCellsCareful2.Reset() # Check to see if anything left extraregion = 0 for cellId in range(numPolys): if (self.checked.GetValue(cellId) == 0 or self.checkedcarefully.GetValue(cellId == 0)): self.NewScalars.InsertValue(cellId, reg + 1) self.AddCellArea(cellId, area) extraregion = 1 if (extraregion): print("I am incrementing region") reg += 1 #Copy all the input geometry and data to the output output.SetPoints(inpts) output.SetPolys(inPolys) output.GetPointData().PassData(input.GetPointData()) output.GetCellData().PassData(input.GetCellData()) #Add the new scalars array to the output self.NewScalars.SetName(self.RegionIdsArrayName) output.GetCellData().AddArray(self.NewScalars) output.GetCellData().SetActiveScalars(self.RegionIdsArrayName) # If extracting largets region, get it out if (self.ExtractLargestRegion): maxVal = 0.0 maxRegion = -1 for i in range(reg): if (self.RegionAreas.GetValue(i) > maxVal): maxVal = self.RegionAreas.GetValue(i) maxRegion = i + 1 thresholder = vtk.vtkThreshold() thresholder.SetIntputData(output) thresholder.SetInputArrayToProcess(0, 0, 0, 1, self.RegionIdsArrayName) thresholder.ThresholdBetween(maxRegion, maxRegion) thresholder.Update() # Check to see if the result has points, don't run surface filter if (thresholder.GetOutput().GetNumberOfPoints() == 0): raise RuntimeError("vtkThreshold Output has no points") #Convert unstructured grid to polydata surfacer = vtk.vtkDataSetSurfaceFilter() surfacer.SetInputData(thresholder.GetOutput()) surfacer.Update() #Set the final pd output.DeepCopy(surfacer.GetOutput()) # Total number of regions self.NumberOfRegions = reg writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = self.OutputFile writer.Input = output writer.Execute()
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() 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] bifurcation_info = {} for i in range(centerlines.GetNumberOfCells()): bifurcation_info[i] = {"clip_id": [], "cell_id": []} 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] 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) if (size_ratio > 2.0): continue cv, offset, shape = ComputeBranchSectionShape( cutPoly, point) if (cv > 0.2): continue if (offset > 0.10): continue #if(shape > 0.8): # continue #else: #average area #radius2 = max(radius, np.sqrt(area_test/np.pi)) #shape = ComputeBranchSectionShape(cutPoly, point, size_range) writerline = vmtkscripts.vmtkSurfaceWriter() writerline.OutputFileName = "test_loop_{0}.vtp".format( pd_count) writerline.Input = cutPoly #ex.GetOutput() writerline.Execute() pd_count += 1 #if (radius2 <= 0.0): #radius2 = centerlines.GetPointData().GetArray("MaximumInscribedSphereRadius").GetTuple(cell.GetPointIds().GetId(k))[0] ##if ( radius2 > radius): ##radius = radius2 ##else: ##ratio = radius/radius2 #else: #print(length) clip_id = cell.GetPointIds().GetId(k) bifurcation_info[i]["clip_id"].append(clip_id) bifurcation_info[i]["cell_id"].append(k) break #return #t = [ 1 for i in bifurcation_info.keys() if len(bifurcation_info[i]) == 2] two_bif = False pd_count = 0 for cell in bifurcation_info: id_sorted = sorted(bifurcation_info[cell]["cell_id"]) if (len(bifurcation_info[cell]["cell_id"]) < 2): two_bif = False else: two_bif = True diff = bifurcation_info[cell]["cell_id"][0] - bifurcation_info[ cell]["cell_id"][1] if (abs(diff) < 2): # there is a problem if there less than two points print("houston we got a problem") clip_id = centerlines.GetCell(cell).GetPointIds().GetId(id_sorted[0]) clip_id_m1 = centerlines.GetCell(cell).GetPointIds().GetId( id_sorted[0] + 1) 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) #tree = vtk.vtkModifiedBSPTree() #tree.SetDataSet(surface_reference) #tree.BuildLocator() ##intersect the locator with the line #LineP0 = start_pt ## 200 points #radius_est = centerlines.GetPointData().GetArray("MaximumInscribedSphereRadius").GetTuple(clip_id)[0] ##radii increment is proportional to circumference ##distance between points #cnt_dist = 0.05 #n_radii = int(np.pi*2.0*radius_est/cnt_dist) #dt = radius_est*4.0*cnt_dist #estimate ray step from radius #dtheta = [0.0 + i*(359.0-0.0)/(n_radii-1) for i in range(n_radii)] #[0.0] #out_vector = (0.0,0.0,0.0) #tolerance = 0.0000001 #polylines = vtk.vtkCellArray() #cut_surface = vtk.vtkPolyData() #new_line = vtk.vtkPolyLine() #new_line.GetPointIds().SetNumberOfIds(len(dtheta)+1) #IntersectPointsList = vtk.vtkPoints() #loop_pts_list = vtk.vtkPoints() #IntersectCellsList = vtk.vtkIdList() #for idx, theta in enumerate(dtheta): #IntersectPoints = vtk.vtkPoints() #IntersectCells = vtk.vtkIdList() #code = 0 #count = 1 #rotate = vtk.vtkTransform() #rotate.RotateWXYZ(theta, v_ctr_start) #rotate.Update() ##print(dir(rotate)) ##trans_m = vtk.vtkMatrix4x4() ##rotate.GetMatrix(trans_m) #out_vector = rotate.TransformVector(v_normal_start) #LineP1 = [ c2 + count*dt*c1 for c2, c1 in zip(start_pt, out_vector)] ##print(v_normal_start, out_vector) #while ( code == 0 and count < 10000): #count += 1 #code = tree.IntersectWithLine(LineP0, LineP1, #tolerance, IntersectPoints, #IntersectCells) #LineP1 = [ c2 + count*dt*c1 for c2, c1 in zip(start_pt, out_vector)] #if(count > 10000 and code == 0): #print("no intersection") #continue #if (code != 0): #if(IntersectCells.GetNumberOfIds() > 1): #print(IntersectCells.GetNumberOfIds()) #pt = IntersectPoints.GetPoint(0) ##pt = [ c2 + dt*c1 for c2, c1 in zip(pt, out_vector)] # add some buffer, may not need it #new_pt_id = IntersectPointsList.InsertNextPoint(pt) #new_line.GetPointIds().SetId(idx, new_pt_id) #loop_pts_list.InsertNextPoint(LineP1) #IntersectCellsList.InsertNextId(IntersectCells.GetId(0)) ##print(IntersectPoints.GetPoint(0), IntersectCells.GetId(0) ) #new_line.GetPointIds().SetId(len(dtheta), 0) #print(IntersectPointsList.GetPoint(0)) #print(v_ctr_start, start_pt) #polylines.InsertNextCell(new_line) #cut_surface.SetPoints(IntersectPointsList) #cut_surface.SetLines(polylines) #writerline = vmtkscripts.vmtkSurfaceWriter() #writerline.OutputFileName = "test_loop_{0}.vtp".format(pd_count) #writerline.Input = cut_surface #writerline.Execute() cutter = vtk.vtkCutter() cutter.SetInputData(surface_reference) cutter.SetCutFunction(plane1) cutter.Update() extract = vtk.vtkPolyDataConnectivityFilter() extract.SetInputConnection(cutter.GetOutputPort()) extract.SetExtractionModeToClosestPointRegion() extract.SetClosestPoint(start_pt) extract.Update() loop = extract.GetOutput() weights = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] gencell = vtk.vtkGenericCell() cross_inter = [0.0, 0.0, 0.0] cross_edges = [0.0, 0.0, 0.0] cross_test = [0.0, 0.0, 0.0] test_pt = [0.0, 0.0, 0.0] thresh = 0.0 first_3tris = False for i in range(loop.GetNumberOfCells()): pt1 = loop.GetPoint(loop.GetCell(i).GetPointIds().GetId(0)) pt2 = loop.GetPoint(loop.GetCell(i).GetPointIds().GetId(1)) mid_pt = [(x + y) / 2.0 for x, y in zip(pt2, pt1)] direction = [x - y for x, y in zip(pt2, pt1)] cell_id = locator_cell.FindCell(mid_pt, 0.0001, gencell, test_pt, weights) cell_ = surface_reference.GetCell(cell_id) right = [] left = [] center = [] pt_list = [] for j in range(cell_.GetNumberOfPoints()): #get distance pt_list.append( surface_reference.GetPoint(cell_.GetPointIds().GetId(j))) dist = plane1.EvaluateFunction(pt_list[-1]) if (dist < -thresh): left.append(j) elif (dist > thresh): right.append(j) else: center.append(j) tag = "" if len(center) > 1: # don't do anything its already split on edge tag = "edge" print("edge") elif len(center) > 0: # split into two triangles pt = center[0] tag = "2_tris" else: tag = "3_tris" if (len(left) > 1): #print("left") pt = right[0] elif (len(right) > 1): pt = left[0] else: print("split triangle") edge1 = [x - y for x, y in zip(pt_list[(pt + 1) % 3], pt_list[pt])] edge2 = [x - y for x, y in zip(pt_list[(pt + 2) % 3], pt_list[pt])] vtk.vtkMath.Cross(edge1, edge2, cross_edges) vtk.vtkMath.Normalize(cross_edges) vtk.vtkMath.Cross(edge1, direction, cross_test) vtk.vtkMath.Normalize(cross_test) is_winding = vtk.vtkMath.Dot(cross_edges, cross_test) # switch the winding of the intersection points if (is_winding < 0.0): tmp = pt1 pt1 = pt2 pt2 = tmp if (tag == "3_tris"): if (first_3tris == False): first_3tris = True # first triangle #new_cell = vtk.vtkTriangle() #pts_id_list = [] #pt_id_1 = triangle_pts.InsertNextPoint(pt_list[pt]) #new_cell.GetPointIds().SetId(0, pt_id_1) #pt_id_2 = triangle_pts.InsertNextPoint(pt1) #new_cell.GetPointIds().SetId(1, pt_id_2) #pt_id_3 = triangle_pts.InsertNextPoint(pt2) #new_cell.GetPointIds().SetId(2, pt_id_3) #triangles.InsertNextCell(new_cell) triangle_pts = vtk.vtkPoints() quad_id_1 = triangle_pts.InsertNextPoint(pt2) quad_id_2 = triangle_pts.InsertNextPoint(pt1) quad_id_3 = triangle_pts.InsertNextPoint(pt_list[(pt + 1) % 3]) quad_id_4 = triangle_pts.InsertNextPoint(pt_list[(pt + 2) % 3]) pts_new_triangle = [] pt_id_2 = surface_reference.GetPoints().InsertNextPoint(pt1) pts_new_triangle.append( surface_reference.GetCell(cell_id).GetPointIds().GetId(pt)) pts_new_triangle.append(pt_id_2) surface_reference.GetPointData().GetArray( "Ids").InsertNextTuple([pt_id_2]) pt_id_2_old = surface_reference.GetCell( cell_id).GetPointIds().GetId((pt + 1) % 3) #surface_reference.GetCell(cell_id).GetPointIds().SetId((pt+1)%3, pt_id_2) pt_id_3 = surface_reference.GetPoints().InsertNextPoint(pt2) pts_new_triangle.append(pt_id_3) surface_reference.GetPointData().GetArray( "Ids").InsertNextTuple([pt_id_2]) pt_id_3_old = surface_reference.GetCell( cell_id).GetPointIds().GetId((pt + 2) % 3) #surface_reference.GetCell(cell_id).GetPointIds().SetId((pt+2)%3, pt_id_3) surface_reference.ReplaceCell(cell_id, len(pts_new_triangle), pts_new_triangle) # map polygon to reference mesh map_to = { quad_id_1: pt_id_3, quad_id_2: pt_id_2, quad_id_3: pt_id_2_old, quad_id_4: pt_id_3_old } npts = 4 polygon = vtk.vtkPolygon() polygon.GetPointIds().SetNumberOfIds(npts) polygon.GetPoints().SetNumberOfPoints(npts) polygon.GetPointIds().SetId(0, quad_id_1) polygon.GetPoints().SetPoint(0, triangle_pts.GetPoint(quad_id_1)) polygon.GetPointIds().SetId(1, quad_id_2) polygon.GetPoints().SetPoint(1, triangle_pts.GetPoint(quad_id_2)) polygon.GetPointIds().SetId(2, quad_id_3) polygon.GetPoints().SetPoint(2, triangle_pts.GetPoint(quad_id_3)) polygon.GetPointIds().SetId(3, quad_id_4) polygon.GetPoints().SetPoint(3, triangle_pts.GetPoint(quad_id_4)) quad_ids = vtk.vtkIdList() polygon.Triangulate(quad_ids) numPts = quad_ids.GetNumberOfIds() numSimplices = numPts // 3 triPts = [0, 0, 0] triPts_map = [0, 0, 0] #print(numSimplices, numPts for j in range(numSimplices): for k in range(3): triPts[k] = polygon.GetPointIds().GetId( quad_ids.GetId(int(3 * j + k))) triPts_map[k] = map_to[triPts[k]] #triangles.InsertNextCell(3, triPts) cell_id_new = surface_reference.GetPolys().InsertNextCell( 3, triPts_map) surface_reference.GetCellData().GetArray( "Ids").InsertNextTuple([cell_id_new]) #surface_reference.Modified() #print("hello") #if ( tag == "2_tris"): ## doesnt' work well ## for collapse of intersection line on #new_cell = vtk.vtkTriangle() #pts_id_list = [] #pt_id_1 = triangle_pts.InsertNextPoint(pt_list[pt]) #new_cell.GetPointIds().SetId(0, pt_id_1) #pt_id_2 = triangle_pts.InsertNextPoint(pt_list[(pt+1)%3]) #new_cell.GetPointIds().SetId(1, pt_id_2) #pt_id_3 = triangle_pts.InsertNextPoint(pt2) #new_cell.GetPointIds().SetId(2, pt_id_3) #triangles.InsertNextCell(new_cell) #new_cell = vtk.vtkTriangle() #new_cell.GetPointIds().SetId(0, pt_id_1) #new_cell.GetPointIds().SetId(1, pt_id_3) #pt_id_4 = triangle_pts.InsertNextPoint(pt_list[(pt+2)%3]) #new_cell.GetPointIds().SetId(2, pt_id_4) #triangles.InsertNextCell(new_cell) #triangle_pd.SetPoints(triangle_pts) #triangle_pd.SetPolys(triangles) #pass_ = vtk.vtkPassArrays() #pass_.SetInputData(surface_reference) #pass_.RemoveArraysOn() #pass_.RemoveCellDataArray("Ids") #pass_.RemoveCellDataArray("Normals") #pass_.RemovePointDataArray("Ids") #pass_.RemovePointDataArray("Normals") ##pass_.ClearPointDataArrays() ##pass_.ClearCellDataArrays() #pass_.Update() #geom = vtk.vtkGeometryFilter() #geom.SetInputConnection(pass_.GetOutputPort()) #geom.Update() #normalsFilter2 = vmtkscripts.vmtkSurfaceNormals() #normalsFilter2.ComputeCellNormals = 1 #normalsFilter2.Surface = surface_reference #normalsFilter2.NormalsArrayName = 'Normals' #normalsFilter2.Execute() #writer = vmtkscripts.vmtkSurfaceWriter() #writer.OutputFileName = "test_file_{0}.vtp".format(pd_count) #writer.Input = surface_reference #geom.GetOutput() #triangle_pd #extract.GetOutput() #writer.Execute() pd_count += 1 #print("yp") surface_reference.Modified() #print("zzz") surface_reference.BuildCells() surface_reference.BuildLinks() #print("yppp") locator_surf = vtk.vtkPointLocator() locator_surf.SetDataSet(surface_reference) locator_surf.BuildLocator() #print("ydddp") locator_cell = vtk.vtkCellLocator() locator_cell.SetDataSet(surface_reference) locator_cell.BuildLocator() #return print(bifurcation_info) #return normalsFilter2 = vmtkscripts.vmtkSurfaceNormals() normalsFilter2.ComputeCellNormals = 1 normalsFilter2.Surface = surface_reference normalsFilter2.NormalsArrayName = 'Normals' normalsFilter2.Execute() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = normalsFilter2.Surface writer.Execute()
def run_script(args): print("extract dome from clipped cfd surface") reader_dome = vmtkscripts.vmtkSurfaceReader() reader_dome.InputFileName = args.surface_file reader_dome.Execute() dome_surface = reader_dome.Surface wall_reader = vmtkscripts.vmtkSurfaceReader() wall_reader.InputFileName = args.wall_file wall_reader.Execute() #mesh_reader = vmtkscripts.vmtkMeshReader() #mesh_reader.InputFileName = args.mesh_file #mesh_reader.Execute() #mesh2surf = vmtkscripts.vmtkMeshToSurface() #mesh2surf.Mesh = mesh_reader.Mesh #mesh2surf.CleanOutput = 0 #mesh2surf.Execute() #scale_cfd = vmtkscripts.vmtkSurfaceScaling() #scale_cfd.ScaleFactor = 1000 # meters to mm #scale_cfd.Surface = mesh2surf.Surface #scale_cfd.Execute() dist = vmtkscripts.vmtkSurfaceDistance() dist.Surface = wall_reader.Surface dist.ReferenceSurface = dome_surface dist.DistanceArrayName = "distance" dist.DistanceVectorsArrayName = "distance_vectors" dist.SignedDistanceArrayName = "signed_distance" dist.Execute() clip_copy = vtk.vtkPolyData() clip_copy.DeepCopy(dist.Surface) clip = vmtkscripts.vmtkSurfaceClipper() clip.Surface = dist.Surface clip.Interactive = 0 clip.InsideOut = 1 clip.ClipArrayName = "distance" clip.ClipValue = 0.1 clip.Execute() conn = vmtkscripts.vmtkSurfaceConnectivity() conn.Surface = clip.Surface conn.Method = "largest" conn.CleanOutput = 0 conn.Execute() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = conn.Surface #accept defaults normals.Execute() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.file_out writer.Input = normals.Surface writer.Execute() if (args.inverse_out): clip_inverse = vmtkscripts.vmtkSurfaceClipper() clip_inverse.Surface = clip_copy clip_inverse.Interactive = 0 clip_inverse.InsideOut = 0 clip_inverse.ClipArrayName = "distance" clip_inverse.ClipValue = 0.1 clip_inverse.Execute() conn2 = vmtkscripts.vmtkSurfaceConnectivity() conn2.Surface = clip_inverse.Surface conn2.Method = "all" conn2.CleanOutput = 0 conn2.Execute() writer2 = vmtkscripts.vmtkSurfaceWriter() writer2.OutputFileName = args.inverse_out writer2.Input = conn2.Surface writer2.Execute()
def Execute(args): print("get average along line probes") reader_lines = vmtkscripts.vmtkSurfaceReader() reader_lines.InputFileName = args.lines_file reader_lines.Execute() lines_surface = reader_lines.Surface n_cells = lines_surface.GetNumberOfCells() n_pts = lines_surface.GetCell(0).GetNumberOfPoints() lines = np.empty((n_cells, n_pts)) pts = np.empty((n_cells, 3)) da = lines_surface.GetPointData().GetArray("NRRDImage") for i in range(n_cells): cellids = lines_surface.GetCell(i).GetPointIds() #n_pts = cell.GetNumberOfPoints() for j in range(n_pts): if (j == n_pts // 2): pts[i, :] = np.array(lines_surface.GetPoint(cellids.GetId(j))) lines[i, j] = lines_surface.GetPointData().GetArray( "NRRDImage").GetTuple(cellids.GetId(j))[0] ln_avg = np.average(lines, axis=1) ln_std = np.std(lines, axis=1, ddof=1) ln_skew = skew(lines, axis=1, bias=False) avg_min = ln_avg.min() ln_avg_norm = (ln_avg + avg_min) / (ln_avg.max() + avg_min) # get weighted average x = np.linspace(-args.slice_thickness, args.slice_thickness, lines.shape[1]) std = args.slice_thickness / 2.0 mean = 0.0 dist = 1.0 / np.sqrt(2.0 * np.pi * std**2) * np.exp(-(x - mean)**2 / (2.0 * std**2)) ln_avg_weight = np.average(lines, axis=1, weights=dist) reader_surface = vmtkscripts.vmtkSurfaceReader() reader_surface.InputFileName = args.surface_file reader_surface.Execute() Surface = reader_surface.Surface #Create the tree pointLocator = vtk.vtkPointLocator() pointLocator.SetDataSet(Surface) pointLocator.BuildLocator() array = vtk.vtkDoubleArray() array.SetNumberOfComponents(n_pts) array.SetName("rawImageSamples") array.SetNumberOfTuples(n_cells) avg = vtk.vtkDoubleArray() avg.SetNumberOfComponents(1) avg.SetName("avgSample") avg.SetNumberOfTuples(n_cells) avg_norm = vtk.vtkDoubleArray() avg_norm.SetNumberOfComponents(1) avg_norm.SetName("normalized") avg_norm.SetNumberOfTuples(n_cells) stddev = vtk.vtkDoubleArray() stddev.SetNumberOfComponents(1) stddev.SetName("stddev") stddev.SetNumberOfTuples(n_cells) skewness = vtk.vtkDoubleArray() skewness.SetNumberOfComponents(1) skewness.SetName("skewness") skewness.SetNumberOfTuples(n_cells) weighted_avg = vtk.vtkDoubleArray() weighted_avg.SetNumberOfComponents(1) weighted_avg.SetName("weighted_average") weighted_avg.SetNumberOfTuples(n_cells) for i in range(n_cells): surf_id = pointLocator.FindClosestPoint(pts[i]) #print(ln_avg.shape) avg.SetValue(surf_id, ln_avg[i]) array.SetTuple(surf_id, list(lines[i, :])) avg_norm.SetValue(surf_id, ln_avg_norm[i]) stddev.SetValue(surf_id, ln_std[i]) skewness.SetValue(surf_id, ln_skew[i]) weighted_avg.SetValue(surf_id, ln_avg_weight[i]) Surface.GetPointData().AddArray(avg) Surface.GetPointData().AddArray(array) Surface.GetPointData().AddArray(avg_norm) Surface.GetPointData().AddArray(stddev) Surface.GetPointData().AddArray(skewness) Surface.GetPointData().AddArray(weighted_avg) writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.file_out writer.Input = Surface writer.Execute()
def Execute(args): print("evaluate centerlines") reader_ctr = vmtkscripts.vmtkSurfaceReader() reader_ctr.InputFileName = args.centerlines reader_ctr.Execute() centerlines = reader_ctr.Surface locator_cell = vtk.vtkPointLocator() locator_cell.SetDataSet(centerlines) locator_cell.BuildLocator() reader_br = vmtkscripts.vmtkSurfaceReader() reader_br.InputFileName = args.boundary_reference reader_br.Execute() boundary_reference = reader_br.Surface terminal_pts = boundary_reference.GetNumberOfPoints() avg_area = vtk.vtkDoubleArray() avg_area.SetName("avg_crosssection") avg_area.SetNumberOfComponents(1) avg_area.SetNumberOfTuples(terminal_pts) #for j in range(centerlines.GetCellData().GetNumberOfArrays()): #new_array = centerlines.GetCellData().GetArray(j) #array_name = centerlines.GetCellData().GetArrayName(j) ##new_array.SetNumberOfTuples(terminal_pts) #boundary_reference.GetPointData().AddArray(new_array) ##boundary_reference.GetPointData().GetArray(array_name).SetNumberOfTuples(terminal_pts) #writer = vmtkscripts.vmtkSurfaceWriter() #writer.OutputFileName = "test_out.vtp" #writer.Input = boundary_reference #writer.Execute() for i in range(terminal_pts): pt = boundary_reference.GetPoint(i) #B ctr_ptId = locator_cell.FindClosestPoint(pt) cell_ids_list = vtk.vtkIdList() centerlines.GetPointCells(ctr_ptId, cell_ids_list) if (cell_ids_list.GetNumberOfIds() > 1): print("something has gone wrong, this is a bifurcation point") else: new_tuple = centerlines.GetCellData().GetArray( "avg_crosssection").GetTuple(cell_ids_list.GetId(0)) avg_area.SetTuple(i, new_tuple) #for j in range(centerlines.GetCellData().GetNumberOfArrays()): #print(cell_ids_list.GetId(0)) #new_tuple = centerlines.GetCellData().GetArray(j).GetTuple(cell_ids_list.GetId(0)) #array_name = centerlines.GetCellData().GetArrayName(j) ##print(array_name) #boundary_reference.GetPointData().GetArray(array_name).SetTuple(i, new_tuple) boundary_reference.GetPointData().AddArray(avg_area) writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = boundary_reference writer.Execute()
def warp_surface(args): print("warp the surface ") reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = args.surface reader.Execute() Surface = reader.Surface narrays = Surface.GetPointData().GetNumberOfArrays() has_normals = False for i in range(narrays): if ( Surface.GetPointData().GetArrayName(i) == "Normals"): has_normals = True break if(has_normals): normals = Surface print("already have") else: get_normals = vtk.vtkPolyDataNormals() get_normals.SetInputData(Surface) get_normals.SetFeatureAngle(30.0) # default get_normals.SetSplitting(True) get_normals.Update() get_normals.GetOutput().GetPointData().SetActiveVectors("Normals") normals = get_normals.GetOutput() print("normals generated") random = vtk.vtkRandomAttributeGenerator() random.SetInputData(normals) random.SetDataTypeToDouble() random.GeneratePointScalarsOn () random.SetComponentRange(-0.5, 0.5) random.Update() #n = random.GetOutput().GetPointData().GetNumberOfArrays() #for i in range(n): #print(random.GetOutput().GetPointData().GetArrayName(i)) calc = vtk.vtkArrayCalculator() calc.SetInputConnection(random.GetOutputPort()) calc.AddScalarArrayName("RandomPointScalars", 0) calc.AddVectorArrayName("Normals", 0, 1, 2) calc.SetFunction("Normals * RandomPointScalars") calc.SetResultArrayName("RandomLengthNormalVectors") calc.Update() warp = vtk.vtkWarpVector() warp.SetInputConnection(calc.GetOutputPort()) warp.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, "RandomLengthNormalVectors"); warp.SetScaleFactor(args.fuzz_scale) warp.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.file_out writer.Input = warp.GetOutput() writer.Execute()
def vmtksurfacereader(filename): reader = vmtkscripts.vmtkSurfaceReader() reader.InputFileName = filename reader.Execute() return reader.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(args): print("clip surface") mesh_reader = vmtkscripts.vmtkMeshReader() mesh_reader.InputFileName = args.mesh_file mesh_reader.Execute() mesh2surf = vmtkscripts.vmtkMeshToSurface() mesh2surf.Mesh = mesh_reader.Mesh mesh2surf.CleanOutput = 0 mesh2surf.Execute() scale_cfd = vmtkscripts.vmtkSurfaceScaling() scale_cfd.ScaleFactor = args.scale # meters to mm scale_cfd.Surface = mesh2surf.Surface scale_cfd.Execute() surface = vtk.vtkPolyData() surface.DeepCopy(scale_cfd.Surface) reader_trim = vmtkscripts.vmtkSurfaceReader() reader_trim.InputFileName = args.polydata_trim reader_trim.Execute() br_trim = reader_trim.Surface reader_ext = vmtkscripts.vmtkSurfaceReader() reader_ext.InputFileName = args.polydata_ext reader_ext.Execute() br_ext = reader_ext.Surface # have to make sure that they both have the same number of GetNumberOfPoints assert br_trim.GetNumberOfPoints() == br_ext.GetNumberOfPoints() locator = vtk.vtkPointLocator() locator.SetDataSet(br_trim) locator.BuildLocator() point_ext = [0.0, 0.0, 0.0] pt_cross = [0.0, 0.0, 0.0] pt_dot = 0.0 count = 0 for trim_id in range(br_ext.GetNumberOfPoints()): # get extension point point_ext = br_ext.GetPoint(trim_id) #closest trim point point_trim_id = locator.FindClosestPoint(point_ext) point_trim = br_trim.GetPoint(point_trim_id) # check that the points are close to the same direction pt_trim_normal = br_trim.GetPointData().GetArray( "BoundaryNormals").GetTuple(point_trim_id) pt_ext_normal = br_ext.GetPointData().GetArray( "BoundaryNormals").GetTuple(trim_id) #print(pt_trim_normal, pt_ext_normal) pt_dot = vtk.vtkMath.Dot(pt_trim_normal, pt_ext_normal) #vtk.vtkMath.Cross(pt_trim_normal, pt_ext_normal, pt_cross) #print(pt_dot, vtk.vtkMath.Norm(pt_cross))#, pt_cross) if (pt_dot < 0.95): print("help the vectors aren't colinear") assert pt_dot > .95 v = np.array(point_ext) - np.array(point_trim) #pt1 - pt2 v_mag = np.linalg.norm(v) n = v / v_mag # print("should be 1.0", np.linalg.norm(n), n) b1, b2 = hughes_moeller(n) #orthogonal basis #Get maximum radius box_radius = br_ext.GetPointData().GetArray("BoundaryRadius").GetTuple( trim_id) box_radius_trim = br_trim.GetPointData().GetArray( "BoundaryRadius").GetTuple(point_trim_id) #print(box_radius_trim, box_radius) extra_room = args.margin extra_z = 0.0 r_max = extra_room * max([box_radius[0], box_radius_trim[0] ]) # max radius z_max = extra_room * v_mag #create transformation matrix R = np.zeros((4, 4), dtype=np.float64) R[:3, 0] = b1 #x R[:3, 1] = b2 #y R[:3, 2] = n #z R[:3, 3] = np.array(point_trim) # the beginning of the clip R[3, 3] = 1.0 trans_matrix = vtk.vtkTransform() trans_inverse = vtk.vtkTransform() trans_matrix.SetMatrix(list(R.ravel())) #print(trans_matrix.GetMatrix()) trans_inverse.DeepCopy(trans_matrix) trans_inverse.Inverse() # point to define bounds dims_min = [-r_max, -r_max, -extra_z * z_max] dims_max = [r_max, r_max, z_max] planes = vtk.vtkBox() planes.SetBounds(dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) planes.SetTransform(trans_inverse) clipper = vtk.vtkTableBasedClipDataSet() clipper.SetInputData(surface) clipper.SetClipFunction(planes) clipper.InsideOutOff() #clipper.SetMergeTolerance(1.0E-6) clipper.Update() #print(clipper.GetMergeTolerance()) surface = clipper.GetOutput() #test = vtk.vtkCubeSource() #test.SetBounds (dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) #trans_cube = vtk.vtkTransformPolyDataFilter() #trans_cube.SetInputConnection(test.GetOutputPort()) #trans_cube.SetTransform(trans_matrix) #trans_cube.Update() #writer2 = vmtkscripts.vmtkSurfaceWriter() #writer2.OutputFileName = os.path.join(os.path.split(args.out_file)[0], "test_clip_box_{0}.vtp".format(count)) #writer2.Input = trans_cube.GetOutput() #writer2.Execute() count += 1 geom = vtk.vtkGeometryFilter() geom.SetInputData(surface) geom.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file writer.Input = geom.GetOutput() writer.Execute()
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
def Execute(args): print("clip surface") reader_ctr = vmtkscripts.vmtkSurfaceReader() reader_ctr.InputFileName = args.centerlines reader_ctr.Execute() centerlines = reader_ctr.Surface reader_surface = vmtkscripts.vmtkSurfaceReader() reader_surface.InputFileName = args.surface_file reader_surface.Execute() input_surface = reader_surface.Surface dx = args.slice_thickness # only get the first three centroid = [float(i) for i in args.centroid.strip(" ").split(",")][0:3] neck_centroid = np.array(centroid) n_pts = centerlines.GetNumberOfPoints() pt1 = np.array(centerlines.GetPoint(0)) # start point pt2 = np.array(centerlines.GetPoint(n_pts - 1)) # end point #print(pt1, pt2) v = pt2 - pt1 #pt1 - pt2 v_mag = np.linalg.norm(v) n = v / v_mag print("should be 1.0", np.linalg.norm(n), n) b1, b2 = hughes_moeller(n) #orthogonal basis #Get maximum radius radius_range = [0.0, 0.0] centerlines.GetPointData().GetArray( "MaximumInscribedSphereRadius").GetRange(radius_range, 0) print(radius_range) r_max = 2 * radius_range[-1] # max radius #https://en.wikipedia.org/wiki/Vector_projection # get starting point from centroid by projecting centroid onto normal direction neck_projection = np.dot(neck_centroid - pt1, n) * n neck_start_pt = pt1 + neck_projection print(neck_start_pt) #create transformation matrix R = np.zeros((4, 4), dtype=np.float64) R[:3, 0] = b1 #x R[:3, 1] = b2 #y R[:3, 2] = n #z R[:3, 3] = neck_start_pt R[3, 3] = 1.0 trans_matrix = vtk.vtkTransform() trans_inverse = vtk.vtkTransform() trans_matrix.SetMatrix(list(R.ravel())) print(trans_matrix.GetMatrix()) trans_inverse.DeepCopy(trans_matrix) trans_inverse.Inverse() count = 0 # slice along normal a1 = r_max #*b1 a2 = r_max #*b2 start_pt = np.copy(neck_start_pt) result = itertools.cycle([(1., 1.), (-1., 1.), (-1., -1.), (1., -1.)]) end_pt = 0.0 #slice until there some reasonable overlap at the end while (np.linalg.norm(neck_projection + (count - 0.5) * dx * n) < v_mag): print(np.linalg.norm(neck_projection + (count - 0.5) * dx * n), v_mag) step_dx = count * dx * n for i in range(4): box_dir = next(result) # point to define bounds #end_pt = start_pt + box_dir[0]*a1 + box_dir[1]*a2 + step_dx dims = np.array( [[box_dir[0] * r_max, box_dir[1] * r_max, (count + 1) * dx], [0.0, 0.0, count * dx]]) dims_min = list(dims.min(axis=0)) dims_max = list(dims.max(axis=0)) print(dims_min, dims_max) #planes = vtk.vtkBox() #planes.SetBounds (dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) #planes.SetTransform(trans_inverse) surface = vtk.vtkPolyData() surface.DeepCopy(input_surface) #surface = Input for j in range(3): for k in range(2): plane = vtk.vtkPlane() normal = [0.0, 0.0, 0.0] if (k == 0): normal[j] = -1.0 plane.SetOrigin(dims_min) else: normal[j] = 1.0 plane.SetOrigin(dims_max) plane.SetNormal(normal) plane.SetTransform(trans_inverse) #plane.SetTransform(trans_matrix) clipper = vtk.vtkTableBasedClipDataSet() clipper.SetInputData(surface) clipper.SetClipFunction(plane) #clipper.SetOutputPointsPrecision(vtk.vtkAlgorithm.DOUBLE_PRECISION) clipper.InsideOutOn() #clipper.SetMergeTolerance(1.0E-6) clipper.Update() #print(clipper.GetMergeTolerance()) surface = clipper.GetOutput() geom = vtk.vtkGeometryFilter() geom.SetInputData(surface) geom.Update() writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = os.path.join( args.out_dir, "{0}_{1}_quad_{2}.vtp".format(args.out_file, count, i)) writer.Input = geom.GetOutput() writer.Execute() if (count == 1): test = vtk.vtkCubeSource() test.SetBounds(dims_min[0], dims_max[0], dims_min[1], dims_max[1], dims_min[2], dims_max[2]) trans_cube = vtk.vtkTransformPolyDataFilter() trans_cube.SetInputConnection(test.GetOutputPort()) trans_cube.SetTransform(trans_matrix) trans_cube.Update() writer2 = vmtkscripts.vmtkSurfaceWriter() writer2.OutputFileName = os.path.join( args.out_dir, "{0}_{1}_quad{2}_box.vtp".format(args.out_file, count, i)) writer2.Input = trans_cube.GetOutput() writer2.Execute() count += 1
def Execute(self): print("Compute VC orientation") self.ctrliner = vmtkscripts.vmtkCenterlines() self.ctrliner.Surface = self.Surface self.ctrliner.Execute() self.Centerlines = self.ctrliner.Centerlines cc = self.Centerlines ptCoord = [] for c in xrange(cc.GetNumberOfPoints()): ptCoord.append(cc.GetPoints().GetPoint(c)) ptCoord = np.array(ptCoord) datamean = ptCoord.mean(axis=0) uu, dd, vv = np.linalg.svd(ptCoord - datamean) # vector of the general direction of the VC # print(vv[0], datamean, datamean+10*vv[0]) VCvect = vv[0] if self.ComputeCenterlines: # print(self.Surface) self.ctrliner = vmtkscripts.vmtkCenterlines() self.ctrliner.Surface = self.Surface # self.ctrliner.SeedSelector = 'openprofiles' self.ctrliner.Execute() self.Centerlines = self.ctrliner.Centerlines # self.Surface = self.Centerlines else: self.Centerlines = self.Surface # if self.Centerlines == None: # self.PrintError('DUMBASS') self.vmtkReader = vmtkscripts.vmtkSurfaceReader() self.vmtkRenderer = vmtkscripts.vmtkRenderer() self.vmtkRenderer.Initialize() self.SurfaceViewer = vmtkscripts.vmtkSurfaceViewer() # self.Surface = self.Centerlines self.SurfaceViewer.Surface = self.Surface self.SurfaceViewer.Execute() self.myattr = vmtkscripts.vmtkCenterlineAttributes() self.myattr.Centerlines = self.Centerlines self.myattr.Execute() self.mybranchextractor = vmtkscripts.vmtkBranchExtractor() self.mybranchextractor.Centerlines = self.myattr.Centerlines self.mybranchextractor.RadiusArrayName = self.RadiusArrayName self.mybranchextractor.Execute() self.ctrl = self.mybranchextractor.Centerlines self.mywriter = vmtkscripts.vmtkSurfaceWriter() self.mywriter.Surface = self.mybranchextractor.Centerlines self.mywriter.OutputFileName = '/home/florian/liverSim/morpho_analysis/test_surf_open_small_ctrlTESTbranc1.vtp' self.mywriter.Execute() self.mybifref = vmtkscripts.vmtkBifurcationReferenceSystems() self.mybifref.Centerlines = self.ctrl self.mybifref.RadiusArrayName = self.RadiusArrayName self.mybifref.BlankingArrayName = self.BlankingArrayName self.mybifref.GroupIdsArrayName = self.GroupIdsArrayName self.mybifref.CenterlineIdsArrayName = self.CenterlineIdsArrayName self.mybifref.TractIdsArrayName = self.TractIdsArrayName self.mybifref.Execute() self.myvect = vmtkscripts.vmtkBifurcationVectors() self.myvect.Centerlines = self.ctrl self.myvect.ReferenceSystems = self.mybifref.ReferenceSystems self.myvect.RadiusArrayName = self.RadiusArrayName self.myvect.BlankingArrayName = self.BlankingArrayName self.myvect.GroupIdsArrayName = self.GroupIdsArrayName self.myvect.TractIdsArrayName = self.TractIdsArrayName self.myvect.CenterlineIdsArrayName = self.CenterlineIdsArrayName self.myvect.ReferenceSystemsNormalArrayName = self.mybifref.ReferenceSystemsNormalArrayName self.myvect.ReferenceSystemsUpNormalArrayName = self.mybifref.ReferenceSystemsUpNormalArrayName self.myvect.Execute() '''TEMP''' self.mywriter = vmtkscripts.vmtkSurfaceWriter() self.mywriter.Surface = self.myvect.BifurcationVectors self.mywriter.OutputFileName = '/home/florian/liverSim/morpho_analysis/test_surf_open_small_bifvect.vtp' self.mywriter.Execute() self.mywriter.Surface = self.ctrl self.mywriter.OutputFileName = '/home/florian/liverSim/morpho_analysis/test_surf_open_small_ctrl.vtp' self.mywriter.Execute() '''/TEMP''' self.numpytator = vmtksurfacetonumpy.vmtkSurfaceToNumpy() self.numpytator.Surface = self.myvect.BifurcationVectors self.numpytator.Execute() vectData = self.numpytator.ArrayDict.values() cprint(figlet_format('Results!', font='bubble')) print('\n InPlaneBifurcationVectors angle:') print(np.degrees(self.angle_between(vectData[0]["InPlaneBifurcationVectors"][1, :], vectData[0]["InPlaneBifurcationVectors"][2, :]))) # print('\n OutOfPlaneBifurcationVectors angle:') # print(np.degrees(self.angle_between(vectData[0]["OutOfPlaneBifurcationVectors"][1, :], # vectData[0]["OutOfPlaneBifurcationVectors"][2, :]))) print('\n bifurcation angle with the VC:') print(np.degrees(self.angle_between(vectData[0]["OutOfPlaneBifurcationVectors"][0, :], VCvect))) ''' weighted average vector between the vectors pointing from the second to the first reference point on each centerline ''' print('\n global direction of the birfurcation:') print(vectData[0]["BifurcationVectors"][0, :]) ''' the origin of the bifurcation is defined as the barycenter of the four reference points weighted by the surface of the maximum inscribed sphere defined on the reference points. The reason of the weighting is that small branches have less impact on the position of the bifurcation origin ''' print('\n Origin of the bifurcation:') print(vectData[1][0]) pass
def Execute(args): print("split 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.ConvertLinesToPointsOff() #cleaner.ToleranceIsOn() cleaner.SetTolerance(args.clean_tol) # assumes mm #print(cleaner.GetTolerance()) cleaner.SetInputData(reader_ctr.Surface) cleaner.Update() centerlines = cleaner.GetOutput() else: centerlines = reader_ctr.Surface centerlines.BuildLinks() centerlines.BuildCells() #if(args.clean_ctr): #for i in range(centerlines.GetNumberOfCells()): #if centerlines.GetCell(i).GetCellType() not in (vtk.VTK_POLY_LINE, vtk.VTK_LINE): #centerlines.DeleteCell(i) #centerlines.RemoveDeletedCells() cell_Ids = vtk.vtkIdList() outputLines = vtk.vtkCellArray() output = vtk.vtkPolyData() lengthArray = vtk.vtkDoubleArray() lengthArray.SetName("length") lengthArray.SetNumberOfComponents(1) pts_ids = vtk.vtkIdList() for i in range(centerlines.GetNumberOfCells()): cell = centerlines.GetCell(i) if cell.GetCellType() not in (vtk.VTK_POLY_LINE, vtk.VTK_LINE): continue n_cell_pts = cell.GetNumberOfPoints() prevPoint = centerlines.GetPoint(cell.GetPointIds().GetId(0)) length = 0.0 start_pt_idx = 0 for j in range(n_cell_pts): centerlines.GetPointCells(cell.GetPointIds().GetId(j), cell_Ids) n_pt_neighbors = cell_Ids.GetNumberOfIds() pt_id = cell.GetPointIds().GetId(j) pts_ids.InsertNextId(pt_id) point = centerlines.GetPoint(cell.GetPointIds().GetId(j)) length += vtk.vtkMath.Distance2BetweenPoints(prevPoint, point)**0.5 prevPoint = point if ((j > start_pt_idx and n_pt_neighbors > 1) or (j == n_cell_pts - 1)): #close new_polyline = addPolyLine(pts_ids) # weird issue with duplicate points if they are not removed if (length > 0.0): outputLines.InsertNextCell(new_polyline) lengthArray.InsertNextTuple([length]) start_pt_idx = j if (n_pt_neighbors > 1): pts_ids.Reset() pts_ids.InsertNextId(pt_id) length = 0.0 pts_ids.Reset() output.SetPoints(centerlines.GetPoints()) output.SetLines(outputLines) output.GetCellData().AddArray(lengthArray) for i in range(centerlines.GetPointData().GetNumberOfArrays()): output.GetPointData().AddArray(centerlines.GetPointData().GetArray(i)) writer = vmtkscripts.vmtkSurfaceWriter() writer.OutputFileName = args.out_file if (args.clean_ctr): cleaner2 = vtk.vtkCleanPolyData() cleaner2.PointMergingOn() cleaner2.ConvertLinesToPointsOn() cleaner2.SetInputData(output) cleaner2.Update() writer.Input = cleaner2.GetOutput() else: writer.Input = output writer.Execute()