def test_type_invalid(): with pytest.raises(TypeError): light = pyvista.Light(light_type=['invalid']) with pytest.raises(ValueError): light = pyvista.Light(light_type='invalid') light = pyvista.Light() with pytest.raises(TypeError): light.light_type = ['invalid']
def test_transforms(): position = (1, 2, 3) focal_point = (4, 5, 6) light = pyvista.Light(position=position) light.focal_point = focal_point trans_array = np.arange(4 * 4).reshape(4, 4) trans_matrix = pyvista.vtkmatrix_from_array(trans_array) assert light.transform_matrix is None light.transform_matrix = trans_array assert isinstance(light.transform_matrix, vtk.vtkMatrix4x4) array = pyvista.array_from_vtkmatrix(light.transform_matrix) assert np.array_equal(array, trans_array) light.transform_matrix = trans_matrix matrix = light.transform_matrix assert all( matrix.GetElement(i, j) == trans_matrix.GetElement(i, j) for i in range(4) for j in range(4)) linear_trans = trans_array[:-1, :-1] shift = trans_array[:-1, -1] assert light.position == position assert np.allclose(light.world_position, linear_trans @ position + shift) assert light.focal_point == focal_point assert np.allclose(light.world_focal_point, linear_trans @ focal_point + shift) with pytest.raises(ValueError): light.transform_matrix = 'invalid'
def test_positioning(): light = pyvista.Light() position = (1, 1, 1) light.position = position assert light.position == position # with no transformation matrix this is also the world position assert light.world_position == position focal_point = (2, 2, 2) light.focal_point = focal_point assert light.focal_point == focal_point # with no transformation matrix this is also the world focal point assert light.world_focal_point == focal_point elev, azim = (30, 60) expected_position = (np.sqrt(3) / 2 * 1 / 2, np.sqrt(3) / 2 * np.sqrt(3) / 2, 1 / 2) light.positional = True light.set_direction_angle(elev, azim) assert not light.positional assert light.focal_point == (0, 0, 0) assert np.allclose(light.position, expected_position) with pytest.raises(AttributeError): light.world_position = position with pytest.raises(AttributeError): light.world_focal_point = focal_point
def test_type_setters(): light = pyvista.Light() light.set_headlight() assert light.is_headlight light.set_camera_light() assert light.is_camera_light light.set_scene_light() assert light.is_scene_light
def test_positional(): light = pyvista.Light() # default is directional light assert not light.positional light.positional = True assert light.positional light.positional = False assert not light.positional
def test_switch_state(): light = pyvista.Light() light.switch_on() assert light.on light.switch_off() assert not light.on light.on = False assert not light.on
def test_lighting_remove_manual_light(): plotter = pyvista.Plotter(lighting=None) plotter.add_mesh(pyvista.Sphere()) plotter.add_light(pyvista.Light()) # test light removal plotter.remove_all_lights() assert not plotter.renderer.lights plotter.show(before_close_callback=verify_cache_image)
def test_type_properties(int_code, enum_code): light = pyvista.Light() # test that the int and enum codes match up assert int_code == enum_code # test that both codes work light.light_type = int_code assert light.light_type == int_code light.light_type = enum_code assert light.light_type == enum_code
def test_copy(): light = pyvista.Light() for name, value, _ in configuration: setattr(light, name, value) deep = light.copy() assert deep == light assert deep.transform_matrix is not light.transform_matrix shallow = light.copy(deep=False) assert shallow == light assert shallow.transform_matrix is light.transform_matrix
def test_eq(): light = pyvista.Light() other = pyvista.Light() for light_now in light, other: for name, value, _ in configuration: setattr(light_now, name, value) assert light == other # check that changing anything will break equality for name, value, _ in configuration: original_value = getattr(other, name) restore_transform = False if value is pyvista.Light.CAMERA_LIGHT: changed_value = pyvista.Light.HEADLIGHT restore_transform = True elif isinstance(value, bool): changed_value = not value elif isinstance(value, (int, float)): changed_value = 0 elif isinstance(value, tuple): changed_value = (0.5, 0.5, 0.5) else: # transform_matrix; value is an ndarray changed_value = -value setattr(other, name, changed_value) assert light != other setattr(other, name, original_value) if restore_transform: # setting the light type cleared the transform other.transform_matrix = light.transform_matrix # sanity check that we managed to restore the original state assert light == other # check None vs transform_matrix case other.transform_matrix = None assert light != other
def test_shape(): light = pyvista.Light() exponent = 1.5 light.exponent = exponent assert light.exponent == exponent cone_angle = 45 light.cone_angle = cone_angle assert light.cone_angle == cone_angle attenuation_values = (3, 2, 1) light.attenuation_values = attenuation_values assert light.attenuation_values == attenuation_values
def test_lighting_add_manual_light(): plotter = pyvista.Plotter(lighting=None) plotter.add_mesh(pyvista.Sphere()) # test manual light addition light = pyvista.Light() plotter.add_light(light) assert plotter.renderer.lights == [light] # failing case with pytest.raises(TypeError): plotter.add_light('invalid') plotter.show(before_close_callback=verify_cache_image)
def plot_color_sphere(image_file_name, spin_to_rgba_func): import pyvista as pv sphere = pv.Sphere(radius=1.0, start_theta=180, end_theta = 90, phi_resolution=60, theta_resolution=60) sphere["spins_rgba"] = spin_to_rgba_func(sphere.points) pv.start_xvfb() plotter = pv.Plotter( off_screen=True, shape=(1,1), lighting=None) light = pv.Light(light_type='headlight') # these don't do anything for a headlight: light.position = (1, 2, 3) light.focal_point = (4, 5, 6) plotter.add_light(light) plotter.add_mesh(sphere, scalars="spins_rgba", specular=0.7, ambient=0.4, specular_power=5, rgb=True, smooth_shading=True) plotter.set_background("white") plotter.show(screenshot=image_file_name + ".png")
def test_init(): position = (1, 1, 1) focal_point = (2, 2, 2) color = (0.5, 0.5, 0.5) light_type = 'headlight' light = pyvista.Light(position=position, focal_point=focal_point, color=color, light_type=light_type) assert isinstance(light, pyvista.Light) assert light.position == position assert light.focal_point == focal_point assert light.ambient_color == color assert light.diffuse_color == color assert light.specular_color == color assert light.light_type == light.HEADLIGHT # check repr too assert repr(light) is not None
def test_lighting_subplots(): plotter = pyvista.Plotter(shape='1|1') plotter.add_mesh(pyvista.Sphere()) renderers = plotter.renderers light = pyvista.Light() plotter.remove_all_lights() for renderer in renderers: assert not renderer.lights plotter.subplot(0) plotter.add_light(light, only_active=True) assert renderers[0].lights and not renderers[1].lights plotter.add_light(light, only_active=False) assert renderers[0].lights and renderers[1].lights plotter.subplot(1) plotter.add_mesh(pyvista.Sphere()) plotter.remove_all_lights(only_active=True) assert renderers[0].lights and not renderers[1].lights plotter.show(before_close_callback=verify_cache_image)
def test_actors(): light = pyvista.Light() actor = light._actor # test showing assert not actor.GetVisibility() light.show_actor() assert not actor.GetVisibility() light.positional = True light.show_actor() assert actor.GetVisibility() # test hiding light.positional = False assert not actor.GetVisibility() light.positional = True light.show_actor() assert actor.GetVisibility() light.hide_actor() assert not actor.GetVisibility() light.show_actor() light.cone_angle = 90 assert not actor.GetVisibility()
def test_from_vtk(): vtk_light = vtk.vtkLight() # set the vtk light for _, value, vtkname in configuration: vtk_setter = getattr(vtk_light, vtkname) if isinstance(value, np.ndarray): # we can't pass the array to vtkLight directly value = pyvista.vtkmatrix_from_array(value) vtk_setter(value) light = pyvista.Light.from_vtk(vtk_light) for pvname, value, _ in configuration: if isinstance(value, np.ndarray): trans_arr = pyvista.array_from_vtkmatrix(getattr(light, pvname)) assert np.array_equal(trans_arr, value) else: assert getattr(light, pvname) == value # invalid case with pytest.raises(TypeError): pyvista.Light.from_vtk('invalid') with pytest.raises(TypeError): pyvista.Light('invalid')
def test_init(): position = (1, 1, 1) focal_point = (2, 2, 2) color = (0.5, 0.5, 0.5) light_type = 'headlight' cone_angle = 15 intensity = 2 exponent = 1.5 positional = True show_actor = False shadow_attenuation = 0.5 light = pyvista.Light(position=position, focal_point=focal_point, color=color, light_type=light_type, cone_angle=cone_angle, intensity=intensity, exponent=exponent, show_actor=show_actor, positional=positional, shadow_attenuation=shadow_attenuation) assert isinstance(light, pyvista.Light) assert light.position == position assert light.focal_point == focal_point assert light.ambient_color == color assert light.diffuse_color == color assert light.specular_color == color assert light.light_type == light.HEADLIGHT assert light.cone_angle == cone_angle assert light.intensity == intensity assert light.exponent == exponent assert light.positional == positional assert light.actor.GetVisibility() == show_actor assert light.shadow_attenuation == shadow_attenuation # check repr too assert repr(light) is not None
def test_colors(): light = pyvista.Light() color = (0, 1, 0) light.diffuse_color = color assert light.diffuse_color == color color = (0, 0, 1) light.specular_color = color assert light.specular_color == color color = (1, 0, 0) light.ambient_color = color assert light.ambient_color == color # test whether strings raise but don't test the result for valid in 'white', 'r', '#c0ffee': light.diffuse_color = valid light.specular_color = valid light.ambient_color = valid with pytest.raises(ValueError): light.diffuse_color = 'invalid' with pytest.raises(ValueError): light.specular_color = 'invalid' with pytest.raises(ValueError): light.ambient_color = 'invalid'
functionality of which can be enabled for spotlights: """ # sphinx_gallery_thumbnail_number = 1 import numpy as np import pyvista as pv from pyvista import examples cow = examples.download_cow() cow.rotate_x(90) plotter = pv.Plotter(lighting='none', window_size=(1000, 1000)) plotter.add_mesh(cow, color='white') floor = pv.Plane(center=(*cow.center[:2], cow.bounds[-2]), i_size=30, j_size=25) plotter.add_mesh(floor, color='green') UFO = pv.Light(position=(0, 0, 10), focal_point=(0, 0, 0), color='white') UFO.positional = True UFO.cone_angle = 40 UFO.exponent = 10 UFO.intensity = 3 UFO.show_actor() plotter.add_light(UFO) # enable shadows to better demonstrate lighting plotter.enable_shadows() plotter.camera_position = [(28, 30, 22), (0.77, 0, -0.44), (0, 0, 1)] plotter.show() ###############################################################################
plotter.add_mesh(mesh, color='white') plotter.show() ############################################################################### # Again we can check what kind of lights this setting uses: plotter = pv.Plotter(lighting='three lights') light_types = [light.light_type for light in plotter.renderer.lights] # Remove from plotters so output is not produced in docs pv.plotting._ALL_PLOTTERS.clear() light_types ############################################################################### # Custom lighting # =============== # # We can introduce our own lighting from scratch by disabling any lighting # on plotter initialization. Adding a single scene light to a scene will # often result in ominous visuals due to objects having larger regions in # shadow: plotter = pv.Plotter(lighting='none') plotter.add_mesh(mesh, color='white') light = pv.Light() light.set_direction_angle(30, 0) plotter.add_light(light) plotter.show()
mesh = examples.download_dragon() mesh.rotate_x(90) mesh.rotate_z(120) ############################################################################### # Using two lights, plot the Stanford Dragon with shadows. # # .. Note:: # VTK has known issues when rendering shadows on certain window # sizes. Be prepared to experiment with the ``window_size`` # parameter. An initial window size of ``(1000, 1000)`` seems to # work well, which can be manually resized without issue. light1 = pyvista.Light( position=(0, 0.2, 1.0), focal_point=(0, 0, 0), color=[1, 1.0, 0.9843, 1], # Color temp. 5400 K intensity=0.3) light2 = pyvista.Light( position=(0, 1.0, 1.0), focal_point=(0, 0, 0), color=[1, 0.83921, 0.6666, 1], # Color temp. 2850 K intensity=1) # Add a thin box below the mesh bounds = mesh.bounds rnge = (bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]) expand = 1.0 height = rnge[2] * 0.05
# shape of the hemispheres. # # Let's shine a directional light on them, positioned between the hemispheres and # oriented along their centers: plotter = pv.Plotter(lighting='none') hemi = pv.Sphere().clip() hemi.translate((-1, 0, 0)) plotter.add_mesh(hemi, color='cyan', smooth_shading=True) hemi = hemi.copy() hemi.rotate_z(180) plotter.add_mesh(hemi, color='cyan', smooth_shading=True) light = pv.Light(position=(0, 0, 0), focal_point=(-1, 0, 0)) plotter.add_light(light) plotter.show() ############################################################################### # Both hemispheres have their surface lit on the side that faces the light. # This is consistent with the point source positioned at infinity, directed from # the light's nominal position toward the focal point. # # Now let's change the light to a positional light (but not a spotlight): plotter = pv.Plotter(lighting='none') hemi = pv.Sphere().clip() hemi.translate((-1, 0, 0))
========= For headlights the :py:attr:`position` and :py:attr:`focal_point` properties are meaningless. No matter where you move the camera, the light always emanates from the view point: """ # sphinx_gallery_thumbnail_number = 2 import pyvista as pv from pyvista import examples mesh = examples.download_bunny() mesh.rotate_x(90) mesh.rotate_z(180) plotter = pv.Plotter(lighting='none') plotter.add_mesh(mesh, color='tan', smooth_shading=True) light = pv.Light(light_type='headlight') # these don't do anything for a headlight: light.position = (1, 2, 3) light.focal_point = (4, 5, 6) plotter.add_light(light) plotter.show() ############################################################################### # Camera light # ============ # # Camera lights define their :py:attr:`position` and :py:attr:`focal_point` # properties in a coordinate system that is local to the camera. The coordinates # in the scene's coordinate system can be accessed through the :py:attr:`world_position` # and :py:attr:`world_focal_point` read-only properties, respectively. For specifics # of the local coordinate system used for the coordinates please see the documentation
############################################################################### # Combine custom lighting and physically based rendering. # download louis model mesh = examples.download_louis_louvre() mesh.rotate_z(140) plotter = pv.Plotter(lighting=None) plotter.set_background('black') plotter.add_mesh(mesh, color='linen', pbr=True, metallic=0.5, roughness=0.5, diffuse=1) # setup lighting light = pv.Light((-2, 2, 0), (0, 0, 0), 'white') plotter.add_light(light) light = pv.Light((2, 0, 0), (0, 0, 0), (0.7, 0.0862, 0.0549)) plotter.add_light(light) light = pv.Light((0, 0, 10), (0, 0, 0), 'white') plotter.add_light(light) # plot with a good camera position plotter.camera_position = [(9.51, 13.92, 15.81), (-2.836, -0.93, 10.2), (-0.22, -0.18, 0.959)] cpos = plotter.show()
by linear attenuation. Three spotlights with three different attenuation profiles each: """ # sphinx_gallery_thumbnail_number = 3 import pyvista as pv plotter = pv.Plotter(lighting='none') billboard = pv.Plane(direction=(1, 0, 0), i_size=6, j_size=6) plotter.add_mesh(billboard, color='white') all_attenuation_values = [(1, 0, 0), (0, 2, 0), (0, 0, 2)] offsets = [-2, 0, 2] for attenuation_values, offset in zip(all_attenuation_values, offsets): light = pv.Light(position=(0.1, offset, 2), focal_point=(0.1, offset, 1), color='cyan') light.positional = True light.cone_angle = 20 light.intensity = 15 light.attenuation_values = attenuation_values plotter.add_light(light) plotter.view_yz() plotter.show() ############################################################################### # It's not too obvious but it's visible that the rightmost light with quadratic # attenuation has a shorter range than the middle one with linear attenuation. # Although it seems that even the leftmost light with constant attenuation loses # its brightness gradually, this partly has to do with the fact that we sliced
def main(): # device = 'webcam' device = 'android' if device == 'webcam': calib_file = './data/hd310.yaml' elif device == 'android': calib_file = './data/android/calib_android.yaml' else: print('no calib data') with open(calib_file) as file: params = yaml.load(file, Loader=yaml.FullLoader) # img_bg = cv2.imread('./data/sample.png') mtx = np.array(params['camera_matrix']) dist = np.array(params['dist_coefs']) ar_ar = ArucoAR() # ar_ar.set_mesh('./bunny.ply') # ar_ar.set_mesh('./data/bun_zipper.ply', levitate=True) # ar_ar.set_mesh('./data/airplane/F-22 Raptor v1.stl', levitate=True) ar_ar.set_mesh('./data/airplane/rafale.stl', levitate=True) # ar_ar.set_mesh('./data/star_wars/falcon.stl') # ar_ar.set_mesh('./data/uke_obj/ukelele.obj') # tex = examples.download_masonry_texture() tex = examples.download_sky_box_nz_texture() # tex = cv2.imread('./data/uke_obj/some.jpg') # ar_ar.set_mesh() # cap = cv2.VideoCapture(0) cap = cv2.VideoCapture('./data/android/android_auto_focus_off.mp4') # cap.set(cv2.CAP_PROP_AUTOFOCUS, 0) # turn the autofocus off p = pv.Plotter(off_screen=True) try: p.add_mesh(ar_ar.mesh, show_edges=False, texture=tex) except: p.add_mesh(ar_ar.mesh, show_edges=False) # light = pv.Light(color='white', light_type='headlight') # light.SetLightTypeToSceneLight() # p.add_light(light) light = pv.Light(position=(10, 0, -0), light_type='camera light') p.add_light(light) count = 0 dictionary = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50) para = cv2.aruco.DetectorParameters_create() para.cornerRefinementMethod = cv2.aruco.CORNER_REFINE_SUBPIX video_imgs = [] cv2.namedWindow('comb_img', cv2.WINDOW_NORMAL) while (cap.isOpened()): # Capture frame-by-frame ret, frame = cap.read() try: # Display the resulting comb_img if ret: cv2.imshow('comb_img', comb_img) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break except: print('issue in displaying') ar_ar.set_bg_image(frame) # cam_transf_mat = modify_tranf_mat (cam_transf_mat_init,count) # cam_transf_mat = cam_transf_mat_init corners, ids, rejectedImgPoints = cv2.aruco.detectMarkers( frame, dictionary, parameters=para) comb_img = frame if np.all(ids != None): rvec, tvec, _ = cv2.aruco.estimatePoseSingleMarkers( corners, 5, mtx, dist) # print(rvec,"rvec") for i in range(0, ids.size): T = rvec_tvec2mat(rvec[i], tvec[i]) img_fg, mask_fg = ar_ar.get_rendered_img(p, T) comb_img = ar_ar.combine_images(img_fg, mask_fg, ar_ar.img_bg) video_imgs.append(comb_img) # draw axis for the aruco markers # cv2.aruco.drawAxis(comb_img, mtx, dist, rvec[i], tvec[i], 10) # cv2.aruco.drawDetectedMarkers(comb_img, corners) count += 1 # When everything done, release the capture cap.release() cv2.destroyAllWindows() out = cv2.VideoWriter('./video_temp.mp4', cv2.VideoWriter_fourcc(*'MP4V'), 15, (frame.shape[1], frame.shape[0])) for i in range(len(video_imgs)): out.write(video_imgs[i]) out.release()
def test_intensity(): light = pyvista.Light() intensity = 0.5 light.intensity = intensity assert light.intensity == intensity
rng = z.max() - z.min() clim = (z.max() - rng * 1.65, z.max()) pl = pv.Plotter() pl.add_mesh(mesh, scalars=z, cmap='gist_earth', n_colors=10, show_scalar_bar=False, smooth_shading=True, clim=clim) pl.show() ############################################################################### # Show the terrain with custom lighting and shadows pl = pv.Plotter(lighting=None) pl.add_light( pv.Light((3, 1, 0.5), show_actor=True, positional=True, cone_angle=90, intensity=1.2)) pl.add_mesh(mesh, cmap='gist_earth', show_scalar_bar=False, smooth_shading=True, clim=clim) pl.enable_shadows = True pl.show()