def get_data_vtk(self, points_interpol, interpolation_method="linear"): """ Get interpolated data for points_interpol using vtks built-in interpolation methods """ kernels = { "voronoi": vtk.vtkVoronoiKernel(), "gaussian": vtk.vtkGaussianKernel(), "shepard": vtk.vtkShepardKernel(), "linear": vtk.vtkLinearKernel() } pointnumpyarray = np.array( [points_interpol[pt] for pt in points_interpol]) out_u_grid = vtk.vtkUnstructuredGrid() r = vtk.vtkPoints() r.SetData(numpy_to_vtk(pointnumpyarray)) out_u_grid.SetPoints(r) locator = vtk.vtkStaticPointLocator() locator.SetDataSet(self.output) locator.BuildLocator() interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(out_u_grid) interpolator.SetSourceData(self.output) interpolator.SetKernel(kernels[interpolation_method]) interpolator.SetLocator(locator) interpolator.Update() return interpolator.GetOutput().GetPointData()
def probeUnstructuredGridVTKOverLine(self, lineVTK, readerUnstructuredGridVTK, varName, kernel="gaussian", radius=None, nullValue=None): """ Interpolate the data from the Unstructured Grid VTK onto a line (profile). The unstructured grid VTK is supposed to be a 2D surface in 3D space, such as the mesh used in 2D hydraulics models. To probe on them, the surface has to be flattened first. Parameters ---------- lineVTK : vtkLineSource or vtkPoints coordinates of points in the vtkLineSource; the points don't need to ordered, thus they can be just a bunch of points readerUnstructuredGridVTK : vtkUnstructuredGridReader Unstructured Grid VTK reader varName : str name of the variable to be probed kernel : str name of the kernel for interpolation (linear, gaussin, voronoi, Shepard" radius : float radius for interpolation kernels nullValue: float value to be assigned to invalid probing points Returns ------- points: numpy arrays [number of points, 3]; points on the profile probed result array: elev: elevation (z) of points in the profile """ # Get data from the Unstructured Grid VTK reader data = readerUnstructuredGridVTK.GetOutput() # make sure the data is stored at points (for smoother interpolation) cell2point = vtk.vtkCellDataToPointData() cell2point.SetInputData(data) cell2point.Update() data = cell2point.GetOutput() #after this, all data are stored at points, not cell centers. bounds = data.GetBounds() #print("Unstructured Grid VTK bounds = ", bounds) #print("Unstructured Grid number of cells: ", data.GetNumberOfCells()) #print("Unstructured Grid number of points: ", data.GetNumberOfPoints()) if radius is None: boundingArea = (bounds[1] - bounds[0]) * (bounds[3] - bounds[2]) #assume 2D Grid averageCellArea = boundingArea/data.GetNumberOfCells() #average cell area radius = np.sqrt(averageCellArea) #average size of cell radius = 2.0*radius #double the search radius ### make a transform to set all Z values to zero ### flattener = vtk.vtkTransform() flattener.Scale(1.0, 1.0, 0.0) ### flatten the input in case it's not already flat ### i_flat = vtk.vtkTransformFilter() if isinstance(lineVTK, vtk.vtkLineSource): i_flat.SetInputConnection(lineVTK.GetOutputPort()) elif isinstance(lineVTK, vtk.vtkPoints): polydata_temp = vtk.vtkPolyData() polydata_temp.SetPoints(lineVTK) i_flat.SetInputData(polydata_temp) else: raise Exception("lineVTK type,", type(lineVTK),", not supported. Only vtkLineSource and vtkPoints are supported.") i_flat.SetTransform(flattener) ### transfer z elevation values to the source's point scalar data ### s_elev = vtk.vtkElevationFilter() s_elev.SetInputData(data) s_elev.SetHighPoint(0, 0, bounds[5]) s_elev.SetLowPoint(0, 0, bounds[4]) s_elev.SetScalarRange(bounds[4], bounds[5]) s_elev.Update() #print("s_elev = ", s_elev.GetUnstructuredGridOutput()) ### flatten the source data; the Z elevations are already in the scalars data ### s_flat = vtk.vtkTransformFilter() s_flat.SetInputConnection(s_elev.GetOutputPort()) s_flat.SetTransform(flattener) # build the probe using vtkPointInterpolator # construct the interpolation kernel if kernel == 'gaussian': kern = vtk.vtkGaussianKernel() kern.SetSharpness(2) kern.SetRadius(radius) elif kernel == 'voronoi': kern = vtk.vtkVoronoiKernel() elif kernel == 'linear': kern = vtk.vtkLinearKernel() kern.SetRadius(radius) elif kernel == 'Shepard': kern = vtk.vtkShepardKernel() kern.SetPowerParameter(2) kern.SetRadius(radius) else: raise Exception("The specified kernel is not supported.") probe = vtk.vtkPointInterpolator() probe.SetInputConnection(i_flat.GetOutputPort()) probe.SetSourceConnection(s_flat.GetOutputPort()) probe.SetKernel(kern) if nullValue is not None: probe.SetNullValue(nullValue) else: probe.SetNullPointsStrategyToClosestPoint() probe.Update() # (This approach of using vtkProbeFilter is replaced by vtkPointInterpolator for smoother result) # vtkProbeFilter, the probe line is the input, and the underlying dataset is the source. #probe = vtk.vtkProbeFilter() #probe.SetInputConnection(i_flat.GetOutputPort()) #probe.SetSourceConnection(s_flat.GetOutputPort()) #probe.Update() # get the data from the VTK-object (probe) to an numpy array #print("varName =", varName) #print(probe.GetOutput().GetPointData().GetArray(varName)) varProbedValues = VN.vtk_to_numpy(probe.GetOutput().GetPointData().GetArray(varName)) numPoints = probe.GetOutput().GetNumberOfPoints() # get the number of points on the line # get the elevation from the VTK-object (probe) to an numpy array elev = VN.vtk_to_numpy(probe.GetOutput().GetPointData().GetArray("Elevation")) # intialise the points on the line x = np.zeros(numPoints) y = np.zeros(numPoints) z = np.zeros(numPoints) points = np.zeros((numPoints, 3)) # get the coordinates of the points on the line for i in range(numPoints): x[i], y[i], z[i] = probe.GetOutput().GetPoint(i) points[i, 0] = x[i] points[i, 1] = y[i] points[i, 2] = z[i] return points, varProbedValues, elev
def interpolateToVolume(mesh, kernel='shepard', radius=None, N=None, bounds=None, nullValue=None, dims=(25, 25, 25)): """ Generate a ``Volume`` by interpolating a scalar or vector field which is only known on a scattered set of points or mesh. Available interpolation kernels are: shepard, gaussian, or linear. :param str kernel: interpolation kernel type [shepard] :param float radius: radius of the local search :param list bounds: bounding box of the output Volume object :param list dims: dimensions of the output Volume object :param float nullValue: value to be assigned to invalid points |interpolateVolume| |interpolateVolume.py|_ """ if isinstance(mesh, vtk.vtkPolyData): output = mesh else: output = mesh.polydata() if radius is None and not N: colors.printc( "Error in interpolateToVolume(): please set either radius or N", c='r') raise RuntimeError # Create a probe volume probe = vtk.vtkImageData() probe.SetDimensions(dims) if bounds is None: bounds = output.GetBounds() probe.SetOrigin(bounds[0], bounds[2], bounds[4]) probe.SetSpacing((bounds[1] - bounds[0]) / dims[0], (bounds[3] - bounds[2]) / dims[1], (bounds[5] - bounds[4]) / dims[2]) # if radius is None: # radius = min(bounds[1]-bounds[0], bounds[3]-bounds[2], bounds[5]-bounds[4])/3 locator = vtk.vtkPointLocator() locator.SetDataSet(output) locator.BuildLocator() if kernel == 'shepard': kern = vtk.vtkShepardKernel() kern.SetPowerParameter(2) elif kernel == 'gaussian': kern = vtk.vtkGaussianKernel() elif kernel == 'linear': kern = vtk.vtkLinearKernel() else: print('Error in interpolateToVolume, available kernels are:') print(' [shepard, gaussian, linear]') raise RuntimeError() if radius: kern.SetRadius(radius) interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(probe) interpolator.SetSourceData(output) interpolator.SetKernel(kern) interpolator.SetLocator(locator) if N: kern.SetNumberOfPoints(N) kern.SetKernelFootprintToNClosest() else: kern.SetRadius(radius) if nullValue is not None: interpolator.SetNullValue(nullValue) else: interpolator.SetNullPointsStrategyToClosestPoint() interpolator.Update() return Volume(interpolator.GetOutput())
probe.SetSpacing((bounds[1]-bounds[0])/(res-1), (bounds[3]-bounds[2])/(res-1), (bounds[5]-bounds[4])/(res-1)) # Reuse the locator locator = vtk.vtkStaticPointLocator() locator.SetDataSet(output) locator.BuildLocator() # Use a gaussian kernel------------------------------------------------ gaussianKernel = vtk.vtkGaussianKernel() gaussianKernel.SetRadius(0.5) gaussianKernel.SetSharpness(4) print ("Radius: {0}".format(gaussianKernel.GetRadius())) interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(probe) interpolator.SetSourceData(output) interpolator.SetKernel(gaussianKernel) interpolator.SetLocator(locator) interpolator.SetNullPointsStrategyToClosestPoint() # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() interpolator.Update() timer.StopTimer() time = timer.GetElapsedTime() print("Interpolate Points (Volume probe): {0}".format(time)) intMapper = vtk.vtkDataSetMapper()
def translesional_result(centerline_file, wall_file,vtk_file_list, output_dir,minPoint=(0,0,0), prox_dist=5, dist_dist=5): # read centerline centerlineReader = vtk.vtkXMLPolyDataReader() centerlineReader.SetFileName(centerline_file) centerlineReader.Update() centerline = centerlineReader.GetOutput() # read vessel wall wallReader = vtk.vtkSTLReader() wallReader.SetFileName(wall_file) wallReader.Update() # read vtk files vtk_files = [] centerlines = [] if not os.path.exists(output_dir): os.makedirs(output_dir) if not os.path.exists(os.path.join(output_dir,"centerlines")): os.makedirs(os.path.join(output_dir,"centerlines")) # average filter averageFilter = vtk.vtkTemporalStatistics() for file_name in vtk_file_list: reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(file_name) reader.Update() geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInputData(reader.GetOutput()) geomFilter.Update() # scale up the CFD result transform = vtk.vtkTransform() transform.Scale(1000,1000,1000) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputData(geomFilter.GetOutput()) transformFilter.SetTransform(transform) transformFilter.Update() vtk_files.append(transformFilter.GetOutput()) interpolator = vtk.vtkPointInterpolator() interpolator.SetSourceData(transformFilter.GetOutput()) interpolator.SetInputData(centerline) interpolator.Update() # convert to desired unit # get the first element pressure try: first_point_pressure = interpolator.GetOutput().GetPointData().GetArray("p").GetValue(0) except: first_point_pressure = 120 converter = vtk.vtkArrayCalculator() converter.SetInputData(interpolator.GetOutput()) converter.AddScalarArrayName("p") converter.SetFunction("120 + (p - {}) * 921 * 0.0075".format(first_point_pressure)) # 921 = mu/nu = density of blood, 0.0075 converts from Pascal to mmHg, offset 120mmHg at ica converter.SetResultArrayName("p(mmHg)") converter.Update() converter2 = vtk.vtkArrayCalculator() converter2.SetInputData(converter.GetOutput()) converter2.AddVectorArrayName("wallShearStress") converter2.SetFunction("wallShearStress * 921") # 921 = mu/nu = density of blood, 0.0075 converts from Pascal to mmHg, http://aboutcfd.blogspot.com/2017/05/wallshearstress-in-openfoam.html converter2.SetResultArrayName("wallShearStress(Pa)") converter2.Update() # output the probe centerline centerline_output_path = os.path.join( os.path.dirname(centerline_file), output_dir, "centerlines", "centerline_probe_{}.vtp".format(os.path.split(file_name)[1].split("_")[1].split(".")[0]) ) centerlines.append(converter2.GetOutput()) averageFilter.SetInputData(converter2.GetOutput()) averageFilter.Update() centerline = averageFilter.GetOutput() # extract lesion section # get the abscissas of min radius point # Create kd tree kDTree = vtk.vtkKdTreePointLocator() kDTree.SetDataSet(centerline) kDTree.BuildLocator() minIdx = kDTree.FindClosestPoint(minPoint) minPoint_absc = centerline.GetPointData().GetArray("Abscissas_average").GetTuple(minIdx)[0] thresholdFilter = vtk.vtkThreshold() thresholdFilter.ThresholdBetween(minPoint_absc-prox_dist,minPoint_absc+dist_dist) thresholdFilter.SetInputData(centerline) thresholdFilter.SetAllScalars(0) # important !!! thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS,"Abscissas_average"); thresholdFilter.Update() # to vtkpolydata geometryFilter = vtk.vtkGeometryFilter() geometryFilter.SetInputData(thresholdFilter.GetOutput()) geometryFilter.Update() # get closest line connectFilter = vtk.vtkConnectivityFilter() connectFilter.SetExtractionModeToClosestPointRegion() connectFilter.SetClosestPoint(minPoint) connectFilter.SetInputData(geometryFilter.GetOutput()) connectFilter.Update() # compute result values abscissas = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average")) abscissas_unique, index = np.unique(sorted(abscissas), axis=0, return_index=True) pressure = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("p(mmHg)_average")) pressure = [x for _, x in sorted(zip(abscissas,pressure))] pressure = [pressure[x] for x in index] pressure_gradient = np.diff(pressure)/np.diff(abscissas_unique) velocity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("U_average")) velocity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in velocity] velocity = [x for _, x in sorted(zip(abscissas,velocity))] velocity = [velocity[x] for x in index] velocity_gradient = np.diff(velocity)/np.diff(abscissas_unique) vorticity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("vorticity_average")) vorticity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in vorticity] vorticity = [x for _, x in sorted(zip(abscissas,vorticity))] vorticity = [vorticity[x] for x in index] vorticity_gradient = np.diff(vorticity)/np.diff(abscissas_unique) wss = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("wallShearStress(Pa)_average")) wss = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in wss] wss = [wss[x] for x in index] wss = [x for _, x in sorted(zip(abscissas,wss))] wss_gradient = np.diff(wss)/np.diff(abscissas_unique) epsilon = 0.00001 p_ratio = np.mean(pressure[-4:-1])/(np.mean(pressure[0:3])+epsilon) u_ratio = np.mean(velocity[-4:-1])/(np.mean(velocity[0:3])+epsilon) w_ratio = np.mean(vorticity[-4:-1])/(np.mean(vorticity[0:3])+epsilon) wss_ratio = np.mean(wss[-4:-1])/(np.mean(wss[0:3])+epsilon) dp_ratio = np.mean(pressure_gradient[-4:-1])/(np.mean(pressure_gradient[0:3])+epsilon) du_ratio = np.mean(velocity_gradient[-4:-1])/(np.mean(velocity_gradient[0:3])+epsilon) dw_ratio = np.mean(vorticity_gradient[-4:-1])/(np.mean(vorticity_gradient[0:3])+epsilon) dwss_ratio = np.mean(wss_gradient[-4:-1])/(np.mean(wss_gradient[0:3])+epsilon) return_value = { 'translesion peak presssure(mmHg)': np.mean(heapq.nlargest(1, pressure)), 'translesion presssure ratio': p_ratio, 'translesion peak pressure gradient(mmHgmm^-1)': np.mean(heapq.nlargest(1, pressure_gradient)), 'translesion pressure gradient ratio': dp_ratio, 'translesion peak velocity(ms^-1)': np.mean(heapq.nlargest(1, velocity)), 'translesion velocity ratio': u_ratio, 'translesion velocity gradient ratio': du_ratio, 'translesion peak velocity gradient(ms^-1mm^-1)': np.mean(heapq.nlargest(1, velocity_gradient)), 'translesion peak vorticity(ms^-1)': np.mean(heapq.nlargest(1, vorticity)), 'translesion vorticity ratio': w_ratio, 'translesion vorticity gradient ratio': dw_ratio, 'translesion peak vorticity gradient(Pamm^-1)':np.mean(heapq.nlargest(1, vorticity_gradient)), 'translesion peak wss(Pa)': np.mean(heapq.nlargest(1, wss)), 'translesion peak wss gradient(Pamm^-1)': np.mean(heapq.nlargest(1, wss_gradient)), 'translesion wss ratio': wss_ratio, 'translesion wss gradient ratio': dwss_ratio, } return return_value
def centerline_probe_result(centerline_file,vtk_file_list, output_dir,minPoint=(0,0,0), bifurcationPoint=(0,0,0)): # read centerline centerlineReader = vtk.vtkXMLPolyDataReader() centerlineReader.SetFileName(centerline_file) centerlineReader.Update() centerline = centerlineReader.GetOutput() # read vtk files vtk_files = [] centerlines = [] if not os.path.exists(output_dir): os.makedirs(output_dir) if not os.path.exists(os.path.join(output_dir,"centerlines")): os.makedirs(os.path.join(output_dir,"centerlines")) # average filter averageFilter = vtk.vtkTemporalStatistics() for file_name in vtk_file_list: reader = vtk.vtkUnstructuredGridReader() reader.SetFileName(file_name) reader.Update() geomFilter = vtk.vtkGeometryFilter() geomFilter.SetInputData(reader.GetOutput()) geomFilter.Update() # scale up the CFD result transform = vtk.vtkTransform() transform.Scale(1000,1000,1000) # transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter = vtk.vtkTransformFilter() transformFilter.SetInputData(geomFilter.GetOutput()) transformFilter.SetTransform(transform) transformFilter.Update() vtk_files.append(transformFilter.GetOutput()) interpolator = vtk.vtkPointInterpolator() interpolator.SetSourceData(transformFilter.GetOutput()) interpolator.SetInputData(centerline) interpolator.Update() # convert to desired unit # get the first element pressure try: first_point_pressure = interpolator.GetOutput().GetPointData().GetArray("p").GetValue(0) except: first_point_pressure = 120 converter = vtk.vtkArrayCalculator() converter.SetInputData(interpolator.GetOutput()) converter.AddScalarArrayName("p") converter.SetFunction("120 + (p - {}) * 921 * 0.0075".format(first_point_pressure)) # 921 = mu/nu = density of blood, 0.0075 converts from Pascal to mmHg, offset 120mmHg at ica converter.SetResultArrayName("p(mmHg)") converter.Update() # output the probe centerline centerline_output_path = os.path.join( os.path.dirname(centerline_file), output_dir, "centerlines", "centerline_probe_{}.vtp".format(os.path.split(file_name)[1].split("_")[1].split(".")[0]) ) centerlines.append(converter.GetOutput()) averageFilter.SetInputData(converter.GetOutput()) averageFilter.Update() writer = vtk.vtkXMLPolyDataWriter() writer.SetInputData(converter.GetOutput()) writer.SetFileName(centerline_output_path) writer.Update() centerline_output_path = os.path.join( os.path.dirname(centerline_file), output_dir, "centerlines", "centerline_probe_avg.vtp" ) writer = vtk.vtkXMLPolyDataWriter() writer.SetInputData(averageFilter.GetOutput()) writer.SetFileName(centerline_output_path) writer.Update() # plot result plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"result.png") dev_plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"result_dev.png") plot_array = [ "Radius_average", "U_average", "p(mmHg)_average", "vorticity_average", "Curvature_average", "Torsion_average" ] fit_dict = plot_centerline_result( averageFilter.GetOutput(), ["U_average","p(mmHg)_average"], #["Radius_average","U_average","p(mmHg)_average","vorticity_average","Curvature_average","Torsion_average"], plot_array, plot_result_path, dev_plot_result_path, minPoint = minPoint, bifurcationPoint = bifurcationPoint) # extract ica thresholdFilter = vtk.vtkThreshold() thresholdFilter.ThresholdBetween(0,999) thresholdFilter.SetInputData(averageFilter.GetOutput()) thresholdFilter.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS, "CenterlineIds_average") thresholdFilter.Update() if thresholdFilter.GetOutput().GetNumberOfPoints() == 0 or fit_dict == None: tqdm.write("Centerline file {} does not contain suitable number of CenterlineIds".format(centerline_file)) return_value = { 'radius mean(mm)': "NA", 'max radius gradient':"NA", 'radius min(mm)': "NA", 'pressure mean(mmHg)': "NA", 'max pressure gradient(mmHg)': "NA", 'in/out pressure gradient(mmHg)': "NA", 'velocity mean(ms^-1)': "NA", 'max velocity gradient(ms^-1)': "NA", 'peak velocity(ms^-1)': "NA", 'vorticity mean(s^-1)': "NA", 'peak vorticity(s^-1)': "NA" } else: # compute result values abscissas = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Abscissas_average")) radius = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("Radius_average")) pressure = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("p(mmHg)_average")) pressure_gradient = np.diff(pressure)/np.diff(abscissas) velocity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("U_average")) velocity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in velocity] vorticity = vtk_to_numpy(thresholdFilter.GetOutput().GetPointData().GetArray("vorticity_average")) vorticity = [math.sqrt(value[0]**2 + value[1]**2 +value[2]**2 ) for value in vorticity] return_value = { 'radius mean(mm)': np.mean(radius), 'radius min(mm)': np.min(radius), 'max radius gradient': fit_dict["Radius_average"], 'pressure mean(mmHg)': np.mean(pressure), # 'max pressure gradient(mmHg)': np.mean(heapq.nlargest(5, pressure_gradient)), 'max pressure gradient(mmHg)': fit_dict["p(mmHg)_average"], 'in/out pressure gradient(mmHg)': np.mean(pressure[0:5]) - np.mean(pressure[-5:]), 'velocity mean(ms^-1)': np.mean(velocity), 'peak velocity(ms^-1)': np.mean(heapq.nlargest(5, velocity)), 'max velocity gradient(ms^-1)': fit_dict["U_average"], 'vorticity mean(s^-1)': np.mean(vorticity), 'peak vorticity(s^-1)': np.mean(heapq.nlargest(5, vorticity)) } # moving variance matrix mv_fields = [ "Radius_average", "U_average", "p(mmHg)_average", "vorticity_average", "Curvature_average", "Torsion_average" ] mv_windows = np.arange(3,10,2) plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"moving_variance.png") dev_plot_result_path = os.path.join(os.path.dirname(centerline_file),output_dir,"moving_variance_dev.png") mv_matrix_df, mv_dy_matrix_df = moving_variance_matrix(averageFilter.GetOutput(),mv_fields,mv_windows, minPoint = minPoint, bifurcationPoint = bifurcationPoint, result_path = plot_result_path, dev_result_path=dev_plot_result_path) return return_value, mv_matrix_df, mv_dy_matrix_df
plane.SetResolution(res, res) plane.SetOrigin(0, 0, 0) plane.SetPoint1(10, 0, 0) plane.SetPoint2(0, 10, 0) plane.SetCenter(center) plane.SetNormal(0, 1, 0) # Reuse the locator locator = vtk.vtkStaticPointLocator() locator.SetDataSet(output) locator.BuildLocator() # Voronoi kernel------------------------------------------------ voronoiKernel = vtk.vtkVoronoiKernel() interpolator = vtk.vtkPointInterpolator() interpolator.SetInputConnection(plane.GetOutputPort()) interpolator.SetSourceData(output) interpolator.SetKernel(voronoiKernel) interpolator.SetLocator(locator) # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() interpolator.Update() timer.StopTimer() time = timer.GetElapsedTime() print("Interpolate Points (Voronoi): {0}".format(time)) intMapper = vtk.vtkPolyDataMapper() intMapper.SetInputConnection(interpolator.GetOutputPort())
def vtkfile(): csvfile = './sample.csv' colors = vtk.vtkNamedColors() points_reader = vtk.vtkDelimitedTextReader() points_reader.SetFileName(csvfile) points_reader.DetectNumericColumnsOn() points_reader.SetFieldDelimiterCharacters(',') points_reader.SetHaveHeaders(True) table_points = vtk.vtkTableToPolyData() table_points.SetInputConnection(points_reader.GetOutputPort()) table_points.SetXColumn('CentroidX') table_points.SetYColumn('CentroidY') table_points.SetZColumn('CentroidZ') table_points.Update() points = table_points.GetOutput() points.GetPointData().SetActiveScalars('VelocityMagnitude') # range = points.GetPointData().GetScalars().GetRange() box = vtk.vtkImageData() box.SetDimensions([101, 101, 101]) gaussian_kernel = vtk.vtkGaussianKernel() gaussian_kernel.SetSharpness(2) gaussian_kernel.SetRadius(12) interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(box) interpolator.SetSourceData(points) interpolator.SetKernel(gaussian_kernel) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(interpolator.GetOutputPort()) # mapper.SetScalarRange(range) actor = vtk.vtkActor() actor.SetMapper(mapper) # point_mapper = vtk.vtkPointGaussianMapper() # point_mapper.SetInputData(points) # # point_mapper.SetScalarRange(range) # point_mapper.SetScaleFactor(0.6) # point_mapper.EmissiveOff() # point_mapper.SetSplatShaderCode( # "//VTK::Color::Impl\n" # "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n" # "if (dist > 1.0) {\n" # " discard;\n" # "} else {\n" # " float scale = (1.0 - dist);\n" # " ambientColor *= scale;\n" # " diffuseColor *= scale;\n" # "}\n" # ) # # point_actor = vtk.vtkActor() # point_actor.SetMapper(point_mapper) renderer = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(renderer) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) renderer.AddActor(actor) # renderer.AddActor(point_actor) renderer.SetBackground(colors.GetColor3d("SlateGray")) renWin.SetSize(640, 480) renWin.SetWindowName('PointInterpolator') renderer.ResetCamera() renderer.GetActiveCamera().Elevation(-45) iren.Initialize() renWin.Render() iren.Start()
plane.SetResolution(res,res) plane.SetOrigin(0,0,0) plane.SetPoint1(10,0,0) plane.SetPoint2(0,10,0) plane.SetCenter(center) plane.SetNormal(0,1,0) # Reuse the locator locator = vtk.vtkStaticPointLocator() locator.SetDataSet(output) locator.BuildLocator() # Voronoi kernel------------------------------------------------ voronoiKernel = vtk.vtkVoronoiKernel() interpolator = vtk.vtkPointInterpolator() interpolator.SetInputConnection(plane.GetOutputPort()) interpolator.SetSourceData(output) interpolator.SetKernel(voronoiKernel) interpolator.SetLocator(locator) # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() interpolator.Update() timer.StopTimer() time = timer.GetElapsedTime() print("Interpolate Points (Voronoi): {0}".format(time)) intMapper = vtk.vtkPolyDataMapper() intMapper.SetInputConnection(interpolator.GetOutputPort())
probe.SetSpacing((bounds[1] - bounds[0]) / (res - 1), (bounds[3] - bounds[2]) / (res - 1), (bounds[5] - bounds[4]) / (res - 1)) # Reuse the locator locator = vtk.vtkStaticPointLocator() locator.SetDataSet(output) locator.BuildLocator() # Use a gaussian kernel------------------------------------------------ gaussianKernel = vtk.vtkGaussianKernel() gaussianKernel.SetRadius(0.5) gaussianKernel.SetSharpness(4) print("Radius: {0}".format(gaussianKernel.GetRadius())) interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(probe) interpolator.SetSourceData(output) interpolator.SetKernel(gaussianKernel) interpolator.SetLocator(locator) interpolator.SetNullPointsStrategyToClosestPoint() # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() interpolator.Update() timer.StopTimer() time = timer.GetElapsedTime() print("Interpolate Points (Volume probe): {0}".format(time)) intMapper = vtk.vtkDataSetMapper()
def npInterpolateVTK3D(npPoints, npValues, npTargetPoints, ParametreInterpolatorVTK=None): if ParametreInterpolatorVTK == None: ParametreInterpolatorVTK = { 'kernel': 'Gaussian', 'Radius': 10., 'Sharpness': 2. } print('[' + ParametreInterpolatorVTK['kernel'] + ' Interpolation - Radius =' + str(ParametreInterpolatorVTK['Radius']) + ' - Sharpness =' + str(ParametreInterpolatorVTK['Sharpness']) + '] processing... ') # # Set Source Points UnGrid = vtk.vtkUnstructuredGrid() vtkP = vtk.vtkPoints() for [x, y, z] in npPoints: vtkP.InsertNextPoint(x, y, z) UnGrid.SetPoints(vtkP) # Set source Point Values l, c = npValues.shape for i in range(0, c): vtkFA = vtk.vtkFloatArray() vtkFA.SetName('Values' + str(i)) for v in npValues: vtkFA.InsertNextValue(v[i]) UnGrid.GetPointData().AddArray(vtkFA) # Set Target Points vtkTP = vtk.vtkPoints() for [x, y, z] in npTargetPoints: vtkTP.InsertNextPoint(x, y, z) vtkTargetPointsPolyData = vtk.vtkPolyData() vtkTargetPointsPolyData.SetPoints(vtkTP) if ParametreInterpolatorVTK['kernel'] == 'Gaussian': Kernel = vtk.vtkGaussianKernel() Kernel.SetSharpness(ParametreInterpolatorVTK['Sharpness']) Kernel.SetRadius(ParametreInterpolatorVTK['Radius']) if ParametreInterpolatorVTK['kernel'] == 'Voronoi': Kernel = vtk.vtkVoronoiKernel() if ParametreInterpolatorVTK['kernel'] == 'Shepard': Kernel = vtk.vtkShepardKernel() Kernel.SetRadius(ParametreInterpolatorVTK['Radius']) # Build locator locator = vtk.vtkStaticPointLocator() locator.SetDataSet(UnGrid) locator.BuildLocator() # build interpolator interp = vtk.vtkPointInterpolator() interp.SetInputData(vtkTargetPointsPolyData) interp.SetSourceData(UnGrid) interp.SetKernel(Kernel) interp.SetLocator(locator) interp.GetLocator().SetNumberOfPointsPerBucket(5) interp.SetNullPointsStrategyToMaskPoints() interp.Update() outputInterp = interp.GetOutput() pointsArr = outputInterp.GetPoints().GetData() nppointsArr = vtk_to_numpy(pointsArr) pdata = outputInterp.GetPointData() # Convert volocities into Numpy Array npOutputValues = np.zeros((len(npTargetPoints), c)) for i in range(0, c): vtkOutputValues = pdata.GetArray('Values' + str(i)) npOutputValues[:, i] = vtk_to_numpy(vtkOutputValues) return npOutputValues
def main(): points_fn, probe_fn = get_program_parameters() colors = vtk.vtkNamedColors() points_reader = vtk.vtkDelimitedTextReader() points_reader.SetFileName(points_fn) points_reader.DetectNumericColumnsOn() points_reader.SetFieldDelimiterCharacters('\t') points_reader.SetHaveHeaders(True) table_points = vtk.vtkTableToPolyData() table_points.SetInputConnection(points_reader.GetOutputPort()) table_points.SetXColumn('x') table_points.SetYColumn('y') table_points.SetZColumn('z') table_points.Update() points = table_points.GetOutput() points.GetPointData().SetActiveScalars('val') range = points.GetPointData().GetScalars().GetRange() # Read a probe surface stl_reader = vtk.vtkSTLReader() stl_reader.SetFileName(probe_fn) stl_reader.Update() surface = stl_reader.GetOutput() bounds = np.array(surface.GetBounds()) dims = np.array([101, 101, 101]) box = vtk.vtkImageData() box.SetDimensions(dims) box.SetSpacing((bounds[1::2] - bounds[:-1:2]) / (dims - 1)) box.SetOrigin(bounds[::2]) # Gaussian kernel gaussian_kernel = vtk.vtkGaussianKernel() gaussian_kernel.SetSharpness(2) gaussian_kernel.SetRadius(12) interpolator = vtk.vtkPointInterpolator() interpolator.SetInputData(box) interpolator.SetSourceData(points) interpolator.SetKernel(gaussian_kernel) resample = vtk.vtkResampleWithDataSet() resample.SetInputData(surface) resample.SetSourceConnection(interpolator.GetOutputPort()) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(resample.GetOutputPort()) mapper.SetScalarRange(range) actor = vtk.vtkActor() actor.SetMapper(mapper) point_mapper = vtk.vtkPointGaussianMapper() point_mapper.SetInputData(points) point_mapper.SetScalarRange(range) point_mapper.SetScaleFactor(0.6) point_mapper.EmissiveOff() point_mapper.SetSplatShaderCode( "//VTK::Color::Impl\n" "float dist = dot(offsetVCVSOutput.xy,offsetVCVSOutput.xy);\n" "if (dist > 1.0) {\n" " discard;\n" "} else {\n" " float scale = (1.0 - dist);\n" " ambientColor *= scale;\n" " diffuseColor *= scale;\n" "}\n") point_actor = vtk.vtkActor() point_actor.SetMapper(point_mapper) renderer = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(renderer) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) renderer.AddActor(actor) renderer.AddActor(point_actor) renderer.SetBackground(colors.GetColor3d('SlateGray')) renWin.SetSize(640, 480) renWin.SetWindowName('PointInterpolator') renderer.ResetCamera() renderer.GetActiveCamera().Elevation(-45) iren.Initialize() renWin.Render() iren.Start()
def apply_displacement_to_mesh(mesh: Union[vtk.vtkDataObject, str], field: Union[vtk.vtkStructuredGrid, str], save_mesh: Union[bool, str] = False, disp_array_name: str = 'estimatedDisplacement'): """Apply a displacement field to a mesh. The displacement field is stored as an array within a vtkStructuredGrid. :param mesh: Mesh to deform, can either be path to file or vtk object. :type mesh: Union[vtk.vtkDataObject, str] :param field: Grid containing displacement field, can either be path \ to file or vtk object. :type field: Union[vtk.vtkStructuredGrid, str] :param save_mesh: If a file name is passed, the deformed mesh is saved \ to disk, defaults to False :type save_mesh: Union[bool, str], optional :param disp_array_name: Name of array within vtkStructuredGrid containing \ the displacement field, defaults to 'estimatedDisplacement' :type disp_array_name: str, optional :return: Displaced mesh :rtype: vtk.vtkPolyData """ if isinstance(mesh, str): mesh = load_points_from_file(mesh) if isinstance(field, str): field = load_structured_grid(field) # In case the field data was transformed, also transform the test data: scale = 1 # default try: tf = loadTransformationMatrix(field) tf.Inverse() LOGGER.debug("Applying transform") tfFilter = vtk.vtkTransformFilter() tfFilter.SetTransform(tf) tfFilter.SetInputData(field) tfFilter.Update() field = tfFilter.GetOutput() # Apply transformation also to all vector fields: applyTransformation(field, tf) scale = tf.GetMatrix().GetElement(0, 0) #pylint:disable=broad-except except Exception as e: print(e) print("Could not find or apply transformation. Skipping.") # Threshold to ignore all points outside of field i.e. # Points outside of the model: threshold = vtk.vtkThreshold() threshold.SetInputArrayToProcess( 0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, "preoperativeSurface") threshold.ThresholdByLower(0) threshold.SetInputData(field) threshold.Update() fieldInternal = threshold.GetOutput() # Interpolate displacement field to points on mesh kernel = vtk.vtkGaussianKernel() kernel.SetRadius(0.01 * scale) kernel.SetKernelFootprintToRadius() interpolator = vtk.vtkPointInterpolator() interpolator.SetKernel(kernel) interpolator.SetNullPointsStrategyToMaskPoints() interpolator.SetValidPointsMaskArrayName("validInternalPoints") interpolator.SetSourceData(fieldInternal) interpolator.SetInputData(mesh) interpolator.Update() output = interpolator.GetOutput() # Actually displace the points in the mesh by adding the displacement # to the point coordinates displaced_points = vtk.vtkPoints() for i in range(output.GetNumberOfPoints()): p = output.GetPoint(i) displaced_points.InsertNextPoint(p) validInternalPoints = output.GetPointData().GetArray("validInternalPoints") displacement = output.GetPointData().GetArray(disp_array_name) np_disp = numpy_support.vtk_to_numpy(displacement) np_vip = numpy_support.vtk_to_numpy(validInternalPoints) for i in range(output.GetNumberOfPoints()): validity = validInternalPoints.GetTuple1(i) if validity > 0.5: p = output.GetPoint(i) p = np.asarray(p) d = displacement.GetTuple3(i) d = np.asarray(d) p_d = p + d displaced_points.SetPoint(i, p_d[0], p_d[1], p_d[2]) output.SetPoints(displaced_points) if save_mesh: writer = vtk.vtkXMLPolyDataWriter() writer.SetInputData(output) writer.SetFileName(save_mesh) writer.Update() # Undo transformation so that field is 'reset' for future use tf = loadTransformationMatrix(field) LOGGER.debug("Reversing transform") tfFilter = vtk.vtkTransformFilter() tfFilter.SetTransform(tf) tfFilter.SetInputData(field) tfFilter.Update() field = tfFilter.GetOutput() # Apply transformation also to all vector fields: applyTransformation(field, tf) return output
def interpolate_data(self, points, disp, stretch=None, shear=None, on_deformed=True, kernel_radius=3.0, kernel_sharpness=1.0, remove_null=True, return_deformed=True): """ Interpolate data on the mesh. This can be used for comparing experimental and simulation data together. on_deform selects whether to interpolate the data on the original or on the deformed configuration """ if stretch is None: stretch = np.array([]) if shear is None: shear = np.array([]) # We need nPts*3 data for vtk if points.shape[1] == 2: points_ = np.zeros([points.shape[0], 3]) points_[:,0:2] = points # Deform data if needed if on_deformed: points_[:,0:2] = points + disp # Generate vtk points structure with all data vtkpoints = vtk.vtkPoints() vtkpoints.SetData(numpy_support.numpy_to_vtk(points_)) vtkdisp = vtk.vtkDoubleArray() vtkdisp.SetName("disp") vtkdisp.SetNumberOfComponents(disp.shape[1]) vtkdisp.SetNumberOfTuples(disp.shape[0]) vtkdisp.SetVoidArray(disp.flatten(), disp.size, 1) vtkstretch = vtk.vtkDoubleArray() vtkstretch.SetName("stretch") vtkstretch.SetNumberOfComponents(1) vtkstretch.SetNumberOfTuples(stretch.size) vtkstretch.SetVoidArray(stretch, stretch.size, 1) shear = shear.reshape([-1, 4]) vtkshear = vtk.vtkDoubleArray() vtkshear.SetName("shear") vtkshear.SetNumberOfComponents(shear.shape[1]) vtkshear.SetNumberOfTuples(shear.shape[0]) vtkshear.SetVoidArray(shear, shear.size, 1) vtkpointset = vtk.vtkPolyData() vtkpointset.SetPoints(vtkpoints) vtkpointset.GetPointData().AddArray(vtkdisp) vtkpointset.GetPointData().AddArray(vtkstretch) vtkpointset.GetPointData().AddArray(vtkshear) # Build the locator for the interpolation locator = vtk.vtkStaticPointLocator() locator.SetDataSet(vtkpointset) locator.BuildLocator() # Build the Gaussian kernel kernel = vtk.vtkGaussianKernel() kernel.SetKernelFootprint(0) kernel.SetRadius(kernel_radius) kernel.SetSharpness(kernel_sharpness) # If the interpolation is performed on the deformed configuration, warp the data if on_deformed: disp_ = np.zeros(self.x_nodes.shape) disp_[:,0:2] = self.disp warpData = vtk.vtkDoubleArray() warpData.SetName("warp") warpData.SetNumberOfComponents(3) warpData.SetNumberOfTuples(self.x_nodes.shape[0]) warpData.SetVoidArray(disp_, self.x_nodes.shape[0], 1) self.vtkmesh.GetPointData().AddArray(warpData) self.vtkmesh.GetPointData().SetActiveVectors(warpData.GetName()) warpVector = vtk.vtkWarpVector() warpVector.SetInputData(self.vtkmesh) warpVector.Update() self.vtkmesh = warpVector.GetOutput() coarseInterpolator = vtk.vtkPointInterpolator() coarseInterpolator.SetSourceData(vtkpointset) coarseInterpolator.SetInputData(self.vtkmesh) coarseInterpolator.SetKernel(kernel) coarseInterpolator.SetLocator(locator) coarseInterpolator.PassPointArraysOff() coarseInterpolator.SetNullPointsStrategyToMaskPoints() # Get points with an invalid interpolation coarseInterpolator.Update() vtkmesh = coarseInterpolator.GetOutput() if return_deformed: self.x_nodes[:,0:2] += self.disp self.disp = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("disp")) self.stretch = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("stretch")) self.shear = numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray("shear")) if remove_null: not_null = (numpy_support.vtk_to_numpy(vtkmesh.GetPointData().GetArray( coarseInterpolator.GetValidPointsMaskArrayName()))).astype(bool) idlist_old = np.arange(self.x_nodes.shape[0])[not_null] self.x_nodes = self.x_nodes[not_null] self.disp = self.disp[not_null] self.stretch = self.stretch[not_null] self.shear = self.shear[not_null] idlist_new = np.arange(self.x_nodes.shape[0]) c1 = np.in1d(self.connec[:, 0], idlist_old) c2 = np.in1d(self.connec[:, 1], idlist_old) c3 = np.in1d(self.connec[:, 2], idlist_old) self.connec = self.connec[np.logical_and(np.logical_and(c1,c2),c3)] for i in idlist_new: self.connec[self.connec == idlist_old[i]] = i points = vtk.vtkPoints() points.SetData(numpy_support.numpy_to_vtk(self.x_nodes)) vtkmesh.SetPoints(points) cells = vtk.vtkCellArray() cells.SetCells(self.connec.shape[0], numpy_support.numpy_to_vtkIdTypeArray(self.connec)) vtkmesh.SetPolys(cells) self.shear = self.shear.reshape([-1, 2, 2])