def demo_text(): viewer = Viewer() viewer.setWindowTitle('BlastSight (Text demo)') # Load a mesh path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' mesh = viewer.load_mesh(path, color=[1.0, 1.0, 0.0], alpha=0.1) # Setup the grid using the bounding box of the figure min_bound, max_bound = mesh.bounding_box viewer.grid.origin = min_bound viewer.grid.size = max_bound - min_bound viewer.grid.color = [1.0, 0.8, 0.0] viewer.grid.mark_separation = 10 viewer.grid.is_visible = True # Showcase orientations viewer.text(text='Facing: Elevation', position=mesh.center, rotation=[0.0, 0.0, 0.0], scale=10) viewer.text(text='Facing: North', position=mesh.center, rotation=[0.0, 90.0, 90.0], scale=10) viewer.text(text='Facing: East', position=mesh.center, rotation=[90.0, 0.0, 0.0], scale=10) viewer.show()
import pathlib from blastsight.view.viewer import Viewer """ In this demo, we'll manually slice a mesh, and detect the vertices of that slice, so we can draw a line there. """ v = Viewer() """ First, we'll load a mesh file. Then, we'll slice the mesh by a plane. We need the plane's normal and any point that belongs to that plane. """ path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' mesh = v.load_mesh(path, color=[0.0, 0.0, 1.0], alpha=0.3) origin = mesh.centroid normal = np.array([0.2, 1.0, 0.8]) slices = v.slice_meshes(origin, normal) """ Then, we'll show the detected vertices. We'll draw them as a line, so the slice is more evident. """ for mesh_slice in slices: vertices = mesh_slice.get('vertices') v.lines(vertices=vertices, color=[0.0, 1.0, 0.0], loop=True) v.fit_to_screen()
Internally, it's a visual effect, which means we have to manually activate the cross-section mode with 'v.set_cross_section(True). This activates the cross-section with default values for the plane. You can change the plane description with v.cross_section(origin, normal), where 'origin' is a point on the plane, and 'normal' is the normal of the plane. To deactivate the cross-section, just use 'v.set_cross_section(False)'. """ v = Viewer() mesh_path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' block_path = f'{pathlib.Path(__file__).parent.parent}/test_files/rainbow.csv' mesh = v.load_mesh(mesh_path, color=[1.0, 0.8, 0.0]) blocks = v.load_blocks(block_path) low, high = v.bounding_box() def scan(origin): v.cross_section(origin, np.array([1.0, 0.0, 0.0])) def scan_left(*args, **kwargs): v.signal_animation_finished.disconnect() v.animate(high, low, scan, duration=2000, steps=60) v.signal_animation_finished.connect(scan_right)
#!/usr/bin/env python import pathlib from blastsight.view.viewer import Viewer """ In this demo, we'll show how you can easily take screenshots of the viewer. """ v = Viewer() path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' v.load_mesh(path) v.fit_to_screen() v.resize(800, 800) """ You can take a screenshot without even seeing the viewer, but if you need to see it anyway, uncomment those "optional" lines. """ for i in range(3): v.show(detached=True, timer=1) # Optional v.take_screenshot(f'screenshot_{i}.png') v.rotation_angle += [0.0, 120.0, 0.0] v.close() # Optional, needed if v.show(detached=True) is used print('Ready!')
import pathlib from blastsight.view.viewer import Viewer """ In this demo, a mesh and a block set will be dynamically sliced by yourself, by clicking in two parts of the screen. """ viewer = Viewer() title = viewer.windowTitle() viewer.setWindowTitle(f'{title} - Click two points in the screen.') mesh_path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' block_path = f'{pathlib.Path(__file__).parent.parent}/test_files/rainbow.csv' mesh = viewer.load_mesh(mesh_path, color=[0.0, 0.8, 0.6], alpha=0.2) blocks = viewer.load_blocks(block_path, alpha=0.1) original_size = blocks.block_size def slice_elements(description: dict) -> None: """ The method slice_elements reacts to viewer.signal_slice_description, and receives a description of the slice, so you can do whatever you want with that information. :param description: Description of the cross-section :return: None """ origin = description.get('origin')
#!/usr/bin/env python import pathlib from blastsight.view.viewer import Viewer """ In this demo, we'll show how you can measure mesh distances from the viewer. """ v = Viewer() title = v.windowTitle() v.setWindowTitle(f'{title} - Click two points of a mesh.') path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' mesh = v.load_mesh(path, color=[0.0, 0.3, 1.0]) phantom_tube = v.tubes(vertices=[mesh.center, mesh.center], color=[1.0, 0.8, 0.0], visible=False) def update_info(d: dict): print(f'Distance dictionary: {d}') distance = d.get('distance') v.setWindowTitle(f'{title} - Distance: {distance}') points = [d.get('point_a'), d.get('point_b')] if distance is None: phantom_tube.is_visible = False else:
#!/usr/bin/env python import pathlib from blastsight.view.viewer import Viewer """ In this demo, we'll show how you can create a basic animation. An animation is interpreted as changing the state of the viewer one frame at the time. That means we'll define a function that makes a change in one single frame. The function must receive a single argument, of the same type of the 'start' and 'end' values. """ v = Viewer() path = f'{pathlib.Path(__file__).parent.parent}/test_files/caseron.off' mesh = v.load_mesh(path, highlight=True) def autorotate(angle): v.set_rotation_angle([0.0, -angle, 0.0]) """ The animate() method receives a 'start' value, an 'end' value, a 'method' (the function that changes one frame in the viewer), and two optional kwargs: 'milliseconds' (how much time should the animation last) and 'steps' (smoothness of the animation depends on this). """ # Start animation v.animate(0, 360, autorotate, milliseconds=3000, steps=100)