def test_extrude_rotate(): resolution = 4 line = pyvista.Line(pointa=(0, 0, 0), pointb=(1, 0, 0)) with pytest.raises(ValueError): line.extrude_rotate(resolution=0) poly = line.extrude_rotate(resolution=resolution) assert poly.n_cells == line.n_points - 1 assert poly.n_points == (resolution + 1) * line.n_points
def show(self, **kwargs): p = pv.Plotter() mesh = pv.PolyData(self.root.points) p.add_mesh(mesh, color='blue', **kwargs) if self.approx_diameter: a, b = self.approx_points line = pv.Line(a, b) p.add_mesh(line, color='red', label=f'approx distance ({self.approx_diameter:.4f})') if self.exact_diameter: a, b = self.exact_points line = pv.Line(a, b) p.add_mesh(line, color='green', label=f'exact distance ({self.exact_diameter:.4f})') p.add_legend() p.show()
def _the_callback(widget, event_id): pointa = widget.GetPoint1() pointb = widget.GetPoint2() if hasattr(callback, '__call__'): if use_vertices: try_callback(callback, pointa, pointb) else: the_line = pyvista.Line(pointa, pointb, resolution=resolution) try_callback(callback, the_line) return
def _make_sticks(self): lines = [] for stick, indices in self.df.groupby("stick id").groups.items(): stickdf = self.df.loc[indices] for (r1, row1), (r2, row2) in zip(stickdf[:-1].iterrows(), stickdf[1:].iterrows()): line = pv.Line( pointa=(row1.X, row1.Y, row1.Z), pointb=(row2.X, row2.Y, row2.Z), ) lines.append(line) self.sticks = lines
def _the_callback(widget, event_id): pointa = widget.GetPoint1() pointb = widget.GetPoint2() if hasattr(callback, '__call__'): if use_vertices: args = [pointa, pointb] else: the_line = pyvista.Line(pointa, pointb, resolution=resolution) args = [the_line] if pass_widget: args.append(widget) try_callback(callback, *args) return
def test_slice_along_line(): model = examples.load_uniform() n = 5 x = y = z = np.linspace(model.bounds[0], model.bounds[1], num=n) points = np.c_[x,y,z] spline = pyvista.Spline(points, n) slc = model.slice_along_line(spline) assert slc.n_points > 0 slc = model.slice_along_line(spline, contour=True) assert slc.n_points > 0 # Now check a simple line a = [model.bounds[0], model.bounds[2], model.bounds[4]] b = [model.bounds[1], model.bounds[3], model.bounds[5]] line = pyvista.Line(a, b, resolution=10) slc = model.slice_along_line(line) assert slc.n_points > 0 # Now check a bad input a = [model.bounds[0], model.bounds[2], model.bounds[4]] b = [model.bounds[1], model.bounds[2], model.bounds[5]] line2 = pyvista.Line(a, b, resolution=10) line = line2.cast_to_unstructured_grid().merge(line.cast_to_unstructured_grid()) with pytest.raises(AssertionError): slc = model.slice_along_line(line)
def getSlugUz(filename, sampleSize): # read vtk as unstructured data data = pv.read(filename) aw = data.point_arrays['alpha.water'] pts = data.points # get alpha.water on the middle line aw = aw[(np.abs(pts[:, 0]) <= 1e-4) & (np.abs(pts[:, 1]) <= 1e-4)] pts = pts[(np.abs(pts[:, 0]) <= 1e-4) & (np.abs(pts[:, 1]) <= 1e-4)] # keep index ind = np.arange(len(aw)).reshape(len(aw), 1) n1 = np.hstack((aw.reshape(len(aw), 1), pts)) n1 = np.hstack((n1, ind)) # sort based on z n1 = n1[n1[:, 3].argsort()] # delete first row n2 = np.delete(n1, (0), axis=0) # copy last row x = n2[-1, :] # append x as the last row of n2 n2 = np.vstack((n2, x)) # find bubble head and tail n3 = n1 - n2 headIndex = n1[n3[:, 0] <= -0.4] tailIndex = n1[n3[:, 0] >= 0.4] m = tailIndex - headIndex[0] p1 = headIndex[0, :].reshape(1, 5) p2 = tailIndex[np.where(m[:, 3] > 0)] sampleZ = 7 sampledP = np.linspace(p1[0, 3], p2[0, 3], num=sampleZ, endpoint=False) sampledP = sampledP[1:] k = np.arange(sampleZ - 1) posOnLine = np.zeros((sampleZ - 1, sampleSize + 1)) uOnline = np.zeros((sampleZ - 1, sampleSize + 1)) for z, i in zip(sampledP, k): # find the nearest point in grid # targetP = pts[np.abs(pts[:,2]-z).argmin()] targetP1 = [0, 0.0825, z] targetP2 = [0, -0.0825, z] line = pv.Line(targetP1, targetP2, resolution=sampleSize) sampled = line.sample(data) sampleUz = sampled['U'][:, 2] posOnLine = sampled['Distance'] uOnline[i, :] = sampleUz return p1, p2, sampledP, posOnLine, uOnline
def test_tube(spline): # Simple line = pyvista.Line() tube = line.tube(n_sides=2) assert tube.n_points, tube.n_cells # inplace line.tube(n_sides=2, inplace=True) assert np.allclose(line.points, tube.points) # Complicated tube = spline.tube(radius=0.5, scalars='arc_length') assert tube.n_points, tube.n_cells with pytest.raises(TypeError): spline.tube(scalars=range(10))
def test_sample_over_line(): """Test that we get a sampled line.""" name = 'values' line = pyvista.Line([0, 0, 0], [0, 0, 10], 9) line[name] = np.linspace(0, 10, 10) sampled_line = line.sample_over_line([0, 0, 0.5], [0, 0, 1.5], 2) expected_result = np.array([0.5, 1, 1.5]) assert np.allclose(sampled_line[name], expected_result) assert name in line.array_names # is name in sampled result # test no resolution sphere = pyvista.Sphere(center=(4.5, 4.5, 4.5), radius=4.5) sampled_from_sphere = sphere.sample_over_line([3, 1, 1], [-3, -1, -1]) assert sampled_from_sphere.n_points == sphere.n_cells + 1 # is sampled result a polydata object assert isinstance(sampled_from_sphere, pyvista.PolyData)
def plot_orientations(self, fmt: str = None, length: float = None, colors=None, **kwargs): if fmt is None: return self._plot_orientations_all() meshes = [] i = self.model._orientations.df.groupby("surface").groups[fmt] if len(i) == 0: return meshes if not length: length = abs( np.min([ np.diff(self.extent[:2]), np.diff(self.extent[2:4]), np.diff(self.extent[4:]) ])) / 10 pts = self.model._orientations.df.loc[i][["X", "Y", "Z"]].values nrms = self.model._orientations.df.loc[i][["G_x", "G_y", "G_z"]].values if colors is None: colors = self._get_color_lot() line_kwargs = dict( color=colors[fmt], line_width=3, ) line_kwargs.update(kwargs) for pt, nrm in zip(pts, nrms): mesh = pv.Line( pointa=pt, pointb=pt + length * nrm, ) if self._actor_exists(mesh): continue self.p.add_mesh(mesh, **line_kwargs) self._actors.append(mesh) meshes.append(mesh) return meshes
def tube(self, origin, destination, radius=1.0, color=(1.0, 1.0, 1.0), scalars=None, vmin=None, vmax=None, colormap='RdBu', normalized_colormap=False, reverse_lut=False): cmap = _get_colormap_from_array(colormap, normalized_colormap) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=FutureWarning) for (pointa, pointb) in zip(origin, destination): line = pyvista.Line(pointa, pointb) if scalars is not None: line.point_arrays['scalars'] = scalars[0, :] scalars = 'scalars' color = None else: scalars = None tube = line.tube(radius) self.plotter.add_mesh(mesh=tube, scalars=scalars, flip_scalars=reverse_lut, rng=[vmin, vmax], color=color, show_scalar_bar=False, cmap=cmap, smooth_shading=self.smooth_shading) return tube
# Slice a mesh perpendicularly along a vector direction perpendicularly. mesh = examples.download_brain() # Create vector vec = np.random.rand(3) # Normalize the vector normal = vec / np.linalg.norm(vec) # Make points along that vector for the extent of your slices a = mesh.center + normal * mesh.length / 3.0 b = mesh.center - normal * mesh.length / 3.0 # Define the line/points for the slices n_slices = 5 line = pv.Line(a, b, n_slices) # Generate all of the slices slices = pv.MultiBlock() for point in line.points: slices.append(mesh.slice(normal=normal, origin=point)) ############################################################################### p = pv.Plotter() p.add_mesh(mesh.outline(), color="k") p.add_mesh(slices, opacity=0.75) p.add_mesh(line, color="red", line_width=5) p.show()
def tertiary_cubes_ray(self, next_cube_face_center, next_cube_face_normal): ''' create cubes within the mesh from the face centers of the first cube''' global next_cube_vol global next_rays, next_ints, next_cube_V, next_cube_F, next_cube_vol_sum, Vol_centroid # # bypass error # try: # next_rays, next_ints, next_cubes, r_num # except NameError: # next_rays = None # next_ints = None # next_cubes = None # r_num = 0 # # remove old rays # if (r_num != 0) and (r_num == int(value[0])): # return # elif (r_num != 0) and (next_cubes != None): # for i in range(0,6): # self.plotter.remove_actor(next_cubes[i]) # for j in range(0, r_num): # self.plotter.remove_actor(next_rays[i*r_num+j]) # self.plotter.remove_actor(next_ints[i*r_num+j]) # track starting time next_cube_start = time.time() # initiate variables next_cube_vol_sum = 0 next_cubes = [0] * 6 # next_cube_face_center = [0] * 6 # next_cube_face_normal = [0] * 6 next_cube_face_center_2 = [0] * 6 next_cube_face_normal_2 = [0] * 6 # print(next_cube_face_center) # face_normal = [0] * 6 next_rays = [0] * 6 * r_num next_ints = [0] * 6 * r_num # fix face_normal normal = next_cube_face_center[0] - Vol_centroid if (np.sign(normal[2]) != np.sign(next_cube_face_normal[0, 2])): next_cube_face_normal = np.negative(next_cube_face_normal) # loop through all 6 faces of max cube for i in range(0, 2): # create rotaional matrix about max cube normals R = self.rot_axis(next_cube_face_normal[i]) # initialize variables ray_size = np.zeros((4, 3)) r_dir = ray_size r_dir_norm = ray_size r_end = ray_size # initialize ray trace parameters l_wid = 3 pt_size = 10 r_len = np.sqrt((x_range / 2)**2 + (y_range / 2)**2 + (z_range / 2)**2) r_int = [] ori_r_int = [] for j in range(0, r_num): for k in range(0, 4): if k == 0: if (i == 0) or (i == 5): r_dir[0] = np.array([ np.sqrt(2) / 2 * np.cos(np.pi / 4 + r_dec * j), np.sqrt(2) / 2 * np.sin(np.pi / 4 + r_dec * j), next_cube_face_normal[i][2] ]) else: x, y = sp.symbols('x,y') f = sp.Eq( next_cube_face_normal[i][0] * x + next_cube_face_normal[i][1] * y, 0) g = sp.Eq(x**2 + y**2, 0.5**2) inc = sp.solve([f, g], (x, y)) r_dir[0] = np.array(next_cube_face_normal[i] + [inc[0][0], inc[0][1], 0.5]) # r_dir[0] = np.array(next_cube_face_normal[i] + [np.negative(next_cube_face_normal[i][0])*np.rint(next_cube_face_center[i][0])*1, np.negative(next_cube_face_normal[i][1])*np.rint(next_cube_face_center[i][1])*1, 1]) r_dir_norm[0] = r_dir[0] / np.linalg.norm(r_dir[0]) r_end[0] = next_cube_face_center[ i] + r_dir_norm[0] * r_len r_end[0] = np.dot(R(j * r_dec), (r_end[0] - Vol_centroid).T).T if i == 1: print(next_cube_face_normal[i]) print(next_cube_face_center[i]) # print(face_center[i]) else: r_end[k] = np.dot(R(k * r_rot), (r_end[0] - Vol_centroid).T).T r_end[k] = r_end[k] + Vol_centroid # perform ray trace r_pts, r_ind = mesh.ray_trace(next_cube_face_center[i], r_end[k]) # show rays next_rays[i * r_num] = self.plotter.add_mesh( pv.Line(next_cube_face_center[i], r_end[k]), color='w', line_width=l_wid) next_ints[i * r_num] = self.plotter.add_mesh( pv.PolyData(r_pts[0]), color='w', point_size=pt_size) # next_rays[i*r_num+k] = self.plotter.add_mesh(pv.Line(next_cube_face_center[i], r_end[k]), color='w', line_width=l_wid) # next_ints[i*r_num+k] = self.plotter.add_mesh(pv.PolyData(r_pts[0]), color='w', point_size=pt_size) # create an array of ray intersections r_int = np.append(r_int, r_pts[0]) # find nearest vertice among the ray intersections r_int = np.reshape(r_int, (4, 3)) ori_nearest, ori_p, ori_V = self.nearest_pt( r_int, next_cube_face_center[i]) r_int = [] ori_r_int = np.append(ori_r_int, ori_V[ori_p, :]) ori_r_int = np.reshape(ori_r_int, (r_num, 3)) face = self.furthest_pt(ori_r_int, next_cube_face_center[i]) # create cube from nearest vertice next_cube_V, next_cube_F, next_cube_vol = self.create_cube( face[2][face[1], :], next_cube_face_center[i], next_cube_face_normal[i]) print(next_cube_face_center[1]) # print(next_cube_face_normal[1]) next_cubes[i] = self.plotter.add_mesh(pv.PolyData( next_cube_V, next_cube_F), show_edges=True, line_width=3, color="y", opacity=0.6) next_cube_face_center_2[i] = np.array( pv.PolyData(next_cube_V, next_cube_F).cell_centers().points) next_cube_face_normal_2[i] = pv.PolyData(next_cube_V, next_cube_F).cell_normals self.plotter.add_mesh(next_cube_face_center[i], color="b", point_size=8.0, render_points_as_spheres=True) # print(next_cube_V) # next cube volume next_cube_vol_sum = next_cube_vol_sum + next_cube_vol # show packing efficiency next_cube_vol_sum = float(format(next_cube_vol_sum, ".5f")) pack_vol = float(format((max_cube_vol + next_cube_vol_sum), ".5f")) pack_percent = "{:.1%}".format(pack_vol / mesh_vol) print("Next Cubes Volume:", next_cube_vol_sum) print("Packed Volume:", pack_vol) print("Packing Efficiency:", pack_percent) # track starting time next_cube_end = time.time() next_cube_run = next_cube_end - next_cube_start print("Total elapsed run time: %g seconds" % (max_cube_run + next_cube_run)) return next_cube_face_center_2, next_cube_face_normal_2
def draw( solver, show_delta_pressures=False, show_streamlines=False, show_wake_vortices=False, ): """Draw the geometry of an airplane object. Citation: Adapted from: vlm3.draw in AeroSandbox Author: Peter Sharpe Date of Retrieval: 03/28/2020 :param solver: SteadyHorseshoeVortexLatticeMethodSolver or SteadyRingVortexLatticeMethodSolver or UnsteadyRingVortexLatticeMethodSolver This is the solver object whose geometry and attributes are to be plotted. :param show_delta_pressures: bool, optional Set this variable to true to show the change in pressure across the panels. The default value is False. :param show_streamlines: bool, optional Set this variable to true to show the streamlines emanating from the back of the wings. The default value is False. :param show_wake_vortices: bool, optional Set this variable to true to show the airplane object's wake ring vortices. The default value is False. :return: None """ # Initialize the plotter and get the plasma color map. plotter = pv.Plotter() color_map = plt.cm.get_cmap("plasma") # Get the solver's geometry. if isinstance( solver, main.unsteady_ring_vortex_lattice_method. UnsteadyRingVortexLatticeMethodSolver, ): airplane = solver.steady_problems[-1].airplane else: airplane = solver.airplane # Initialize empty ndarrays to hold the things to plot. panel_vertices = np.empty((0, 3), dtype=int) panel_faces = np.empty(0, dtype=int) scalars = np.empty(0, dtype=int) # Initialize a variable to keep track of how many panels have been added thus far. current_panel_num = 0 # Increment through the current airplane's wings. for wing in airplane.wings: # Unravel the wing's panel matrix and iterate through it. panels = np.ravel(wing.panels) for panel in panels: # Stack this panel's vertices, faces, and scalars. Look through the PolyData documentation for more # details. panel_vertices_to_add = np.vstack(( panel.front_left_vertex, panel.front_right_vertex, panel.back_right_vertex, panel.back_left_vertex, )) panel_face_to_add = np.array([ 4, (current_panel_num * 4), (current_panel_num * 4) + 1, (current_panel_num * 4) + 2, (current_panel_num * 4) + 3, ]) # Stack this panel's vertices, faces, and scalars with the ndarray of all the vertices, faces, and # scalars. panel_vertices = np.vstack((panel_vertices, panel_vertices_to_add)) panel_faces = np.hstack((panel_faces, panel_face_to_add)) # If the user wants to plot the pressures, add the panel's delta pressure to the ndarray of scalars. if show_delta_pressures: scalar_to_add = panel.delta_pressure scalars = np.hstack((scalars, scalar_to_add)) # Update the number of previous panels. current_panel_num += 1 # Check if the user wants to show the wake vortices. if show_wake_vortices: wake_ring_vortex_vertices = np.empty((0, 3), dtype=int) wake_ring_vortex_faces = np.empty(0, dtype=int) current_wake_ring_vortex_num = 0 # Iterate through the unraveled array of wake vortices for the given wing. for wake_ring_vortex in np.ravel(wing.wake_ring_vortices): wake_ring_vortex_vertices_to_add = np.vstack(( wake_ring_vortex.front_left_vertex, wake_ring_vortex.front_right_vertex, wake_ring_vortex.back_right_vertex, wake_ring_vortex.back_left_vertex, )) wake_ring_vortex_face_to_add = np.array([ 4, (current_wake_ring_vortex_num * 4), (current_wake_ring_vortex_num * 4) + 1, (current_wake_ring_vortex_num * 4) + 2, (current_wake_ring_vortex_num * 4) + 3, ]) wake_ring_vortex_vertices = np.vstack( (wake_ring_vortex_vertices, wake_ring_vortex_vertices_to_add)) wake_ring_vortex_faces = np.hstack( (wake_ring_vortex_faces, wake_ring_vortex_face_to_add)) current_wake_ring_vortex_num += 1 wake_ring_vortex_surface = pv.PolyData(wake_ring_vortex_vertices, wake_ring_vortex_faces) plotter.add_mesh( wake_ring_vortex_surface, show_edges=True, smooth_shading=True, color="white", ) # Initialize the panel surfaces and add the meshes to the plotter. panel_surface = pv.PolyData(panel_vertices, panel_faces) # Check if the user wants to plot pressures. If so, add the panel surfaces to the plotter with the pressure scalars. # Otherwise, add the panel surfaces without the pressure scalars. if show_delta_pressures: plotter.add_mesh( panel_surface, show_edges=True, cmap=color_map, scalars=scalars, smooth_shading=True, ) else: plotter.add_mesh( panel_surface, show_edges=True, cmap=color_map, color="#86C552", smooth_shading=True, ) # Check if the user wants to plot streamlines. if show_streamlines: # Iterate through the spanwise positions in the solver's streamline point matrix. for spanwise_position in range(solver.streamline_points.shape[1]): # Get the column of streamline points at this spanwise position. streamline_point_column = solver.streamline_points[:, spanwise_position, :] # Iterate through each streamline point column. for point_index in range(streamline_point_column.shape[0]): # Skip the first point because it has not previous point with which to make a line. if point_index != 0: # Get the current, and the last point. point = streamline_point_column[point_index, :] last_point = streamline_point_column[point_index - 1, :] # Add a line to make this segment of the streamline. plotter.add_mesh( pv.Line( last_point, point, ), show_edges=True, color="#EEEEEF", line_width=2, ) # Set the plotter background color and show the plotter. plotter.set_background(color="#000000") plotter.show(cpos=(-1, -1, 1), full_screen=False)
def draw_cyl(plotter, tip, base, diam, color, opacity): line = pv.Line(tip, base) tube = line.tube(radius=diam / 2) plotter.add_mesh(tube, opacity=opacity, color=color)
""" import pyvista as pv # Create source to ray trace sphere = pv.Sphere(radius=0.85) # Define line segment start = [0, 0, 0] stop = [0.25, 1, 0.5] # Perfrom ray trace points, ind = sphere.ray_trace(start, stop) # Create geometry to represent ray trace ray = pv.Line(start, stop) intersection = pv.PolyData(points) # Render the result p = pv.Plotter() p.add_mesh(sphere, show_edges=True, opacity=0.5, color="w", lighting=False, label="Test Mesh") p.add_mesh(ray, color="blue", line_width=5, label="Ray Segment") p.add_mesh(intersection, color="maroon", point_size=10, label="Intersection Points")
def cube_center_ray(self, start, dir): ''' from starting point shoot out 8 rays to find vertices of a possible cube, whose face normals would be in either in x,y,z direction, or rotated 45 deg along z-axis ''' # set ray directions if dir == 'z': r1_dir = np.array([1,1,1]) #r2_dir = np.array([1,0,1]) r3_dir = np.array([1,-1,1]) #r4_dir = np.array([0,-1,1]) r5_dir = np.array([-1,-1,1]) #r6_dir = np.array([-1,0,1]) r7_dir = np.array([-1,1,1]) #r8_dir = np.array([0,1,1]) elif dir == '-z': r1_dir = np.array([1,1,-1]) #r2_dir = np.array([1,0,-1]) r3_dir = np.array([1,-1,-1]) #r4_dir = np.array([0,-1,-1]) r5_dir = np.array([-1,-1,-1]) #r6_dir = np.array([-1,0,-1]) r7_dir = np.array([-1,1,-1]) #r8_dir = np.array([0,1,-1]) # set ray length r_len = abs(ranges[4] - ranges[5])/2 * np.sqrt(0.5**2 + (np.sqrt(2)/2)**2) # set ray end points r1_end = start + r1_dir / np.linalg.norm(r1_dir) * r_len #r2_end = start + r2_dir / np.linalg.norm(r2_dir) * r_len r3_end = start + r3_dir / np.linalg.norm(r3_dir) * r_len #r4_end = start + r4_dir / np.linalg.norm(r4_dir) * r_len r5_end = start + r5_dir / np.linalg.norm(r5_dir) * r_len #r6_end = start + r6_dir / np.linalg.norm(r6_dir) * r_len r7_end = start + r7_dir / np.linalg.norm(r7_dir) * r_len #r8_end = start + r8_dir / np.linalg.norm(r8_dir) * r_len # perform ray trace r1_pts, r1_ind = mesh.ray_trace(start, r1_end) #r2_pts, r2_ind = mesh.ray_trace(start, r2_end) r3_pts, r3_ind = mesh.ray_trace(start, r3_end) #r4_pts, r4_ind = mesh.ray_trace(start, r4_end) r5_pts, r5_ind = mesh.ray_trace(start, r5_end) #r6_pts, r6_nd = mesh.ray_trace(start, r6_end) r7_pts, r7_ind = mesh.ray_trace(start, r7_end) #r8_pts, r8_ind = mesh.ray_trace(start, r8_end) # initialize rays r1 = pv.Line(start, r1_end) #r2 = pv.Line(start, r2_end) r3 = pv.Line(start, r3_end) #r4 = pv.Line(start, r4_end) r5 = pv.Line(start, r5_end) #r6 = pv.Line(start, r6_end) r7 = pv.Line(start, r7_end) #r8 = pv.Line(start, r8_end) # initialize intersections r1_int = pv.PolyData(r1_pts[0]) #r2_int = pv.PolyData(r2_pts[0]) r3_int = pv.PolyData(r3_pts[0]) #r4_int = pv.PolyData(r4_pts[0]) r5_int = pv.PolyData(r5_pts[0]) #r6_int = pv.PolyData(r6_pts[0]) r7_int = pv.PolyData(r7_pts[0]) #r8_int = pv.PolyData(r8_pts[0]) # show rays l_wid = 6 #self.plotter.add_mesh(r1, color='w', line_width=l_wid) #self.plotter.add_mesh(r2, color='w', line_width=l_wid) #self.plotter.add_mesh(r3, color='w', line_width=l_wid) #self.plotter.add_mesh(r4, color='w', line_width=l_wid) #self.plotter.add_mesh(r5, color='w', line_width=l_wid) #self.plotter.add_mesh(r6, color='w', line_width=l_wid) #self.plotter.add_mesh(r7, color='w', line_width=l_wid) #self.plotter.add_mesh(r8, color='w', line_width=l_wid) # show intersections pt_size = 20 #self.plotter.add_mesh(r1_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r2_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r3_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r4_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r5_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r6_int, color='w', point_size=pt_size) #elf.plotter.add_mesh(r7_int, color='w', point_size=pt_size) #self.plotter.add_mesh(r8_int, color='w', point_size=pt_size) # array of intersections # r_int = np.vstack([r1_int.points, r2_int.points, r3_int.points, r4_int.points, # r5_int.points, r6_int.points, r7_int.points, r8_int.points]) r_int = np.vstack([r1_int.points, r3_int.points, r5_int.points, r7_int.points]) return r_int
def plot(self, *args, extent=None, color=(0.45, 0.45, 0.45), centre=(0, 0, 0), **kwargs): if extent is None: extent = [1, 1, 1] lattice: coreLattice = self.obj lines = [] # Add major lattice points for z in np.arange(extent[2]): for y in np.arange(extent[1]): for x in np.arange(extent[0]): lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x + 1, y, z]))) lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y + 1, z]))) lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y, z + 1]))) lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x + 1, y + 1, z + 1]), pointb=lattice.get_cartesian_coords([x + 1, y, z + 1]))) lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x + 1, y + 1, z + 1]), pointb=lattice.get_cartesian_coords([x + 1, y + 1, z]))) lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x + 1, y + 1, z + 1]), pointb=lattice.get_cartesian_coords([x, y + 1, z + 1]))) # Draw x lines for x in np.arange(extent[0]): y = extent[1] z = 0 lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x + 1, y, z]))) z = extent[2] y = 0 lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x + 1, y, z]))) # Draw y lines for y in np.arange(extent[1]): x = 0 z = extent[2] lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y + 1, z]))) x = extent[0] z = 0 lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y + 1, z]))) # Draw y lines for z in np.arange(extent[2]): x = 0 y = extent[1] lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y, z + 1]))) x = extent[0] y = 0 lines.append(pyvista.Line(pointa=lattice.get_cartesian_coords([x, y, z]), pointb=lattice.get_cartesian_coords([x, y, z + 1]))) centre_point = lattice.get_cartesian_coords(extent)/2 for line in lines: line.transform(-centre_point) self.actors.append(self.plotter.add_mesh(line, color=color)) self.plotter.reset_camera()
def make_lines(pts): lines = [ pv.Line(pts[0], pts[1]), pv.Line(pts[1], pts[2]), pv.Line(pts[2], pts[3]), pv.Line(pts[3], pts[0]), pv.Line(pts[4], pts[5]), pv.Line(pts[5], pts[6]), pv.Line(pts[6], pts[7]), pv.Line(pts[7], pts[4]), pv.Line(pts[0], pts[4]), pv.Line(pts[1], pts[5]), pv.Line(pts[2], pts[6]), pv.Line(pts[3], pts[7]), ] return lines
def cube_center_ray(self, start, dir): ''' from starting point shoot out n rays to find vertices of possible cubes ''' global r_num, r_rot, r_dec # initialize variables # idx = value.index(" ") # r_num = 0 # for i in range(0, idx): # r_num = r_num + int(value[i]) + (idx - i)**10 r_rot = np.pi / 2 r_num = 1 # r_dec = -2*np.pi/r_num #could include in the future r_dec = 0 l_wid = 5 pt_size = 20 ray_size = np.zeros((4, 3)) r_dir = ray_size r_dir_norm = ray_size r_end = ray_size rays = [0] * r_num ints = [0] * r_num r_int = [] ori_r_int = [] # set ray length r_len = np.sqrt((x_range / 2)**2 + (y_range / 2)**2 + (z_range / 2)**2) # create rays by rotating the first, which creates the cube with xyz axes as its face normals for i in range(0, r_num): for j in range(0, 4): if (j == 0) and (dir == 'z'): r_dir[0] = np.array([ np.sqrt(2) / 2 * np.cos(np.pi / 4 + r_dec * i), np.sqrt(2) / 2 * np.sin(np.pi / 4 + r_dec * i), 0.5 ]) r_dir_norm[0] = r_dir[0] / np.linalg.norm(r_dir[0]) r_end[0] = Vol_centroid + r_dir_norm[0] * r_len # set rotation matrix about 'z' R = self.rot_axis(np.array([0, 0, 1])) elif (j == 0) and (dir == '-z'): r_dir[0] = np.array([ np.sqrt(2) / 2 * np.cos(np.pi / 4 + r_dec * i), np.sqrt(2) / 2 * np.sin(np.pi / 4 + r_dec * i), -0.5 ]) r_dir_norm[0] = r_dir[0] / np.linalg.norm(r_dir[0]) r_end[0] = Vol_centroid + r_dir_norm[0] * r_len # set rotation matrix about '-z' R = self.rot_axis(np.array([0, 0, -1])) else: r_end[j] = np.dot(R(j * r_rot), (r_end[0] - Vol_centroid).T).T r_end[j] = r_end[j] + Vol_centroid # perform ray trace r_pts, r_ind = mesh.ray_trace(Vol_centroid, r_end[j]) # show rays rays[j] = self.plotter.add_mesh(pv.Line( Vol_centroid, r_end[j]), color='w', line_width=l_wid) # rays[1] = self.plotter.add_mesh(pv.Line(Vol_centroid, r_end[1]), color='w', line_width=l_wid) # ints[0] = self.plotter.add_mesh(pv.PolyData(r_pts[0]), color='w', point_size=pt_size) # create an array of ray intersections r_int = np.append(r_int, r_pts[0]) r_int = np.reshape(r_int, (4, 3)) ori_nearest, ori_p, ori_V = self.nearest_pt(r_int, Vol_centroid) r_int = [] ori_r_int = np.append(ori_r_int, ori_V[ori_p, :]) ori_r_int = np.reshape(ori_r_int, (r_num, 3)) return ori_r_int, rays, ints
import pyvista as pv from pyvista import examples ############################################################################### # Volumetric Mesh # +++++++++++++++ # # First a 3D mesh example to demonstrate mesh = examples.download_kitchen() # Make two points to construct the line between a = [mesh.bounds[0], mesh.bounds[2], mesh.bounds[4]] b = [mesh.bounds[1], mesh.bounds[3], mesh.bounds[5]] # Preview how this line intersects this mesh line = pv.Line(a, b) p = pv.Plotter() p.add_mesh(mesh, style="wireframe", color="w") p.add_mesh(line, color="b") p.show() ############################################################################### # Run the filter and produce a line plot mesh.plot_over_line(a, b, resolution=100) ############################################################################### # Flat Surface # ++++++++++++ # # We could also plot the values of a mesh that lies on a flat surface
def plot_datasets(dataset_type=None): """Plot the pyvista dataset types. This demo plots the following PyVista dataset types: * :class:`pyvista.PolyData` * :class:`pyvista.UnstructuredGrid` * :class:`pyvista.UniformGrid` * :class:`pyvista.RectilinearGrid` * :class:`pyvista.StructuredGrid` Parameters ---------- dataset_type : str, optional If set, plot just that dataset. Must be one of the following: * ``'PolyData'`` * ``'UnstructuredGrid'`` * ``'UniformGrid'`` * ``'RectilinearGrid'`` * ``'StructuredGrid'`` Examples -------- >>> from pyvista import demos >>> demos.plot_datasets() """ allowable_types = ['PolyData', 'UnstructuredGrid', 'UniformGrid', 'RectilinearGrid', 'StructuredGrid'] if dataset_type is not None: if dataset_type not in allowable_types: raise ValueError(f'Invalid dataset_type {dataset_type}. Must be one ' f'of the following: {allowable_types}') ########################################################################### # uniform grid image = pv.UniformGrid((6, 6, 1)) image.spacing = (3, 2, 1) ########################################################################### # RectilinearGrid xrng = np.array([0, 0.3, 1, 4, 5, 6, 6.2, 6.6]) yrng = np.linspace(-2, 2, 5) zrng = [1] rec_grid = pv.RectilinearGrid(xrng, yrng, zrng) ########################################################################### # structured grid ang = np.linspace(0, np.pi/2, 10) r = np.linspace(6, 10, 8) z = [0] ang, r, z = np.meshgrid(ang, r, z) x = r*np.sin(ang) y = r*np.cos(ang) struct_grid = pv.StructuredGrid(x[::-1], y[::-1], z[::-1]) ########################################################################### # polydata points = pv.PolyData([[1, 2, 2], [2, 2, 2]]) line = pv.Line() line.points += np.array((2, 0, 0)) line.clear_data() tri = pv.Triangle() tri.points += np.array([0, 1, 0]) circ = pv.Circle() circ.points += np.array([1.5, 1.5, 0]) poly = tri + circ ########################################################################### # unstructuredgrid pyr = pv.Pyramid() pyr.points *= 0.7 cube = pv.Cube(center=(2, 0, 0)) ugrid = circ + pyr + cube + tri if dataset_type is not None: pl = pv.Plotter() else: pl = pv.Plotter(shape='3/2') # polydata if dataset_type is None: pl.subplot(0) pl.add_text('4. PolyData') if dataset_type in [None, 'PolyData']: pl.add_points(points, point_size=20) pl.add_mesh(line, line_width=5) pl.add_mesh(poly) pl.add_mesh(poly.extract_all_edges(), line_width=2, color='k') # unstructuredgrid if dataset_type is None: pl.subplot(1) pl.add_text('5. UnstructuredGrid') if dataset_type in [None, 'UnstructuredGrid']: pl.add_mesh(ugrid) pl.add_mesh(ugrid.extract_all_edges(), line_width=2, color='k') # UniformGrid if dataset_type is None: pl.subplot(2) pl.add_text('1. UniformGrid') if dataset_type in [None, 'UniformGrid']: pl.add_mesh(image) pl.add_mesh(image.extract_all_edges(), color='k', style='wireframe', line_width=2) pl.camera_position = 'xy' # RectilinearGrid if dataset_type is None: pl.subplot(3) pl.add_text('2. RectilinearGrid') if dataset_type in [None, 'RectilinearGrid']: pl.add_mesh(rec_grid) pl.add_mesh(rec_grid.extract_all_edges(), color='k', style='wireframe', line_width=2) pl.camera_position = 'xy' # StructuredGrid if dataset_type is None: pl.subplot(4) pl.add_text('3. StructuredGrid') if dataset_type in [None, 'StructuredGrid']: pl.add_mesh(struct_grid) pl.add_mesh(struct_grid.extract_all_edges(), color='k', style='wireframe', line_width=2) pl.camera_position = 'xy' pl.show()
Sweep polygonal data creating "skirt" from free edges and lines, and lines from vertices. This takes polygonal data as input and generates polygonal data on output. The input dataset is swept around the z-axis to create new polygonal primitives. These primitives form a "skirt" or swept surface. For example, sweeping a line results in a cylindrical shell, and sweeping a circle creates a torus. """ import pyvista import numpy as np # create a line and rotate it about the Z-axis resolution = 10 line = pyvista.Line(pointa=(0, 0, 0), pointb=(1, 0, 0), resolution=2) poly = line.extrude_rotate(resolution=resolution) poly ############################################################################### # Plot the extruded line # ~~~~~~~~~~~~~~~~~~~~~~ plotter = pyvista.Plotter(shape=(2, 1)) plotter.subplot(0, 0) plotter.add_text("Line", font_size=24) plotter.add_mesh(line, color="tan", show_edges=True) plotter.add_mesh( pyvista.PolyData(line.points), color="red", point_size=10,
meshSmallNormals["distances"] = np.empty(meshSmall.n_points) meshSmallNormals["surfacePoints"] = np.empty([meshSmall.n_points, 3]) normalVectors = np.empty([meshSmall.n_points, 6]) for i in range(meshSmallNormals.n_points): p = meshSmallNormals.points[i] #vec = meshSmallNormals["Normals"][i] * meshSmallNormals.length vec = meshSmallNormals["Normals"][i]*2 p0 = p - vec p1 = p + vec ip, ic = meshBig.ray_trace(p0, p1, first_point=True) meshSmallNormals["surfacePoints"][i] = ip dist = np.sqrt(np.sum((ip - p)**2)) meshSmallNormals["distances"][i] = dist if i % 8 == 0: ray = pv.Line(p, ip) pp.add_mesh(ray, color="blue", line_width=3, label="Ray Segment") normalVectors[:, 0:3] = meshSmall.points normalVectors[:, 3:] = meshSmallNormals["surfacePoints"]-meshSmall.points np.savetxt("E13-E15outer.csv",normalVectors) # Replace zeros with nans mask = meshSmallNormals["distances"] == 0 meshSmallNormals["distances"][mask] = np.nan
def create_poly_from_df(df_input, type='spheres', return_poly=True, output_file=None, add_xyzr_extra=True, verbose=False): """ a dataframe with spheres : x,y,z of center, radius should be provided. Additional columns will be added as cell data arrays e.g : x y z radius spID clID ceID lines : x1,y1,z1,x2,y2,z2 int is the default datatype for added cell arrays. an output file location is mandatory because a temporary vtp file must be written to disk, but if not given the paraview VTK object without extra data will be returned output = VTK poly """ df_cell_data = {} if type == 'lines': ix_extra_data = 6 connectivity = 2 # pv.Lines.lines (= a line mesh) elif type == 'spheres': ix_extra_data = 4 connectivity = 3 # pv.Sphere.faces (=a triangulated mesh) elif type == 'vertices': ix_extra_data = 3 connectivity = 1 # pv.Sphere.faces (=a triangulated mesh) if add_xyzr_extra: ix_extra_data = 0 # 1 - creation of the elementary objects (spheres, lines) if type == 'vertices': #vtp_points = np.array(df_input.iloc[:,0:3]) vtp_points = np.transpose( np.vstack([ np.array(df_input['x']), np.array(df_input['y']), np.array(df_input['z']) ])) for i in range(ix_extra_data, len(df_input.columns)): df_cell_data[df_input.columns[i]] = np.array(df_input.iloc[:, i]) else: blocks = pv.MultiBlock() for row_i in df_input.iterrows(): if type == 'spheres': blocks.append( pv.Sphere(radius=row_i[1].radius, center=(row_i[1].x, row_i[1].y, row_i[1].z), direction=(0, 0, 1), theta_resolution=10, phi_resolution=10, start_theta=0, end_theta=360, start_phi=0, end_phi=180)) elif type == 'lines': blocks.append( pv.Line(pointa=(row_i[1].x1, row_i[1].y1, row_i[1].z1), pointb=(row_i[1].x2, row_i[1].y2, row_i[1].z2))) # 2 - creating 1 vtp file # (WATCH OUT, the following destroys the sphere data (updates face information), so we take a copy blocks_copy = blocks.copy(deep=True) vtp_points = np.zeros((0, 3), dtype='float64') vtp_mesh_components = np.zeros((0, ), dtype='int64') for extra_data_column in df_input.columns[ix_extra_data:]: df_cell_data[extra_data_column] = np.zeros((0, ), dtype='int64') for ix_block, block_i in enumerate(blocks_copy): connectivity_i = block_i.lines if type == 'lines' else block_i.faces if verbose: print('the number of points in this block = ', len(block_i.points)) if verbose: print( 'the number of mesh components (triangles, lines..) in this block (sphere, or line or..) = ', len(connectivity_i) / (connectivity + 1)) mesh_components = connectivity_i.reshape((-1, connectivity + 1)) # we need to adjust the points indices in the mesh_components mesh_components[:, 1:] = mesh_components[:, 1:] + len(vtp_points) for extra_data, value in df_cell_data.items(): # the data we will add to Cell (for visualisation and selection in paraview) value_append = np.full((len(mesh_components), ), df_input.at[ix_block, extra_data]) df_cell_data[extra_data] = np.concatenate( (value, value_append)) vtp_points = np.concatenate((vtp_points, block_i.points)) vtp_mesh_components = np.concatenate( (vtp_mesh_components, mesh_components.reshape(-1, ))) #classpyvista.PolyData(var_inp=None, faces=None, n_faces=None, lines=None, n_lines=None, deep=False) if connectivity == 1: pv_mesh = pv.PolyData(vtp_points) elif connectivity == 2: # pyvista bug , turns it into verts instead of lines (e.g 6 verts(=points) instead of 3 lines) pv_mesh = pv.PolyData(vtp_points, lines=vtp_mesh_components) #pv_mesh = pv.PolyData(vtp_points, vtp_mesh_components) else: # faces= does not work for some reason pv_mesh = pv.PolyData(vtp_points, vtp_mesh_components) if output_file: pv_mesh.save(output_file, binary=False) else: return pv_mesh # add the extra cell data arrays poly_mesh = read_vtp_file(output_file) field_type = "POINT" if type == 'vertices' else "CELL" for extra_data_column in df_input.columns[ix_extra_data:]: poly_mesh = add_array(poly_mesh, df_cell_data[extra_data_column], extra_data_column, field_type=field_type, dtype='int') pv_mesh_added = pv.wrap(poly_mesh) pv_mesh_added.save(output_file, binary=False) if verbose: print('Final output vtp file is written to ', output_file) return poly_mesh if return_poly else None
# same thing in pyvista rst = mapdl.result nnum, stress = rst.nodal_stress(0) # get SYZ stress stress_yz = stress[:, 5] # Assign the YZ stress to the underlying grid within the result instance. # For this example, NAN values must be replaced with 0 for the # interpolation to succeed stress_yz[np.isnan(stress_yz)] = 0 rst.grid['Stress YZ'] = stress_yz # Create a line and sample over it line = pv.Line(pl_start, pl_end, resolution=100) out = line.sample(rst.grid) # bug where the interpolation must be run twice out = line.sample(rst.grid) # Note: We could have used a spline (or really, any dataset), and # interpolated over it instead of a simple line. # plot the interpolated stress from VTK and MAPDL plt.plot(out.points[:, 1], out['Stress YZ'], 'x', label='Stress vtk') plt.plot(table[:, 0], table[:, 6], label='Stress MAPDL') plt.legend() plt.xlabel('Y Position (in.)') plt.ylabel('Stress YZ (psi)') plt.show() ############################################################################### # 2D Slice Interpolation
def test_n_lines(): mesh = pyvista.Line() assert mesh.n_lines == 1
The "Hello, world!" of VTK """ import pyvista as pv ############################################################################### # This runs through several of the available geometric objects available in # VTK which PyVista provides simple convenience methods for generating. # # Let's run through creating a few geometric objects! cyl = pv.Cylinder() arrow = pv.Arrow() sphere = pv.Sphere() plane = pv.Plane() line = pv.Line() box = pv.Box() cone = pv.Cone() poly = pv.Polygon() disc = pv.Disc() ############################################################################### # Now let's plot them all in one window p = pv.Plotter(shape=(3, 3)) # Top row p.subplot(0, 0) p.add_mesh(cyl, color="tan", show_edges=True) p.subplot(0, 1) p.add_mesh(arrow, color="tan", show_edges=True) p.subplot(0, 2)
def getSlugUz(filename, sampleSize): # read vtk as unstructured data data = pv.read(filename) aw = data.point_arrays['alpha.water'] pts = data.points D = 0.2 ## get alpha.water on the middle line aw = aw[(np.abs(pts[:, 1] - 0.1) <= 1e-4) & (pts[:, 2] == 0)] pts = pts[(np.abs(pts[:, 1] - 0.1) <= 1e-4) & (pts[:, 2] == 0)] n1 = np.hstack((aw.reshape(len(aw), 1), pts)) # sort based on x n1_sorted = n1[np.argsort(n1[:, 1])] n1_diff = np.diff(n1_sorted[:, 0]) n1_sorted = np.delete(n1_sorted, -1, 0) firstHead_index = np.argmax(n1_diff >= 0.2) firstTail_index = np.argmax(n1_diff <= -0.2) secondHead_index = np.argmax( n1_diff[firstHead_index + 5:] >= 0.2) + firstHead_index + 5 secondTail_index = np.argmax( n1_diff[firstTail_index + 5:] <= -0.2) + firstTail_index + 5 p1 = n1_sorted[firstHead_index, 1] p2 = n1_sorted[firstTail_index, 1] p3 = n1_sorted[secondHead_index, 1] p4 = n1_sorted[secondTail_index, 1] if p2 < p1: ls1 = p4 - p1 ls2 = 4 - p3 + p2 x_mid1 = 0.5 * (p1 + p4) if p3 + p2 > 4: x_mid2 = 0.5 * (p2 + p3) - 2 else: x_mid2 = 2 + 0.5 * (p2 + p3) else: ls1 = p2 - p1 ls2 = p4 - p3 x_mid1 = 0.5 * (p1 + p2) x_mid2 = 0.5 * (p3 + p4) sampleZ = 5 sampleSize = 30 sampledP = np.asarray([x_mid1, x_mid2]) k = np.arange(sampleZ - 1) posOnLine = np.zeros((sampleZ - 1, sampleSize + 1)) uOnline = np.zeros((sampleZ - 1, sampleSize + 1)) for x, i in zip(sampledP, k): # find the nearest point in grid # targetP = pts[np.abs(pts[:,2]-z).argmin()] targetP1 = [0, 0.5 * D, x] targetP2 = [0, -0.5 * D, x] line = pv.Line(targetP2, targetP1, resolution=sampleSize) sampled = line.sample(data) sampleUz = sampled['U'][:, 0] posOnLine = sampled['Distance'] uOnline[i, :] = sampleUz return ls1, ls2, sampledP, posOnLine, uOnline