.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "../../docs/source/_gallery/example_photometric_rendering_on_cylinder.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_.._.._docs_source__gallery_example_photometric_rendering_on_cylinder.py: .. _example_photometric_rendering_on_cylinder: Rendering Photometric Properties on a Cylinder ===================================================================================== .. contents:: Table of Contents :local: :depth: 1 :backlinks: top This example demonstrates how to use the Bouguer law and Ward's BRDF model from the ``pysdic`` library to render photometric properties on a cylindrical mesh. .. seealso:: - :func:`pysdic.compute_bouguer_law` - Official documentation for the Bouguer law function. - :func:`pysdic.compute_brdf_ward` - Official documentation for Ward's BRDF function. .. note:: Other implemented BRDF models can be use in a similar way, such as Beckmann's model using the :func:`pysdic.compute_brdf_beckmann` function. .. GENERATED FROM PYTHON SOURCE LINES 28-33 Define some points on a cylinder surface -------------------------------------------------------------------------------- Construct some points on a cylinder surface using cylindrical coordinates. The cylinder is defined by its radius and height range. .. GENERATED FROM PYTHON SOURCE LINES 33-60 .. code-block:: Python import numpy theta_min = -numpy.pi theta_max = numpy.pi height_min = -1.0 height_max = 1.0 radius = 1.0 nt = 1000 # Number of points along the circumference nh = 100 # Number of points along the height theta = numpy.linspace(theta_min, theta_max, nt) height = numpy.linspace(height_min, height_max, nh) theta_grid, height_grid = numpy.meshgrid(theta, height) # points x = radius * numpy.cos(theta_grid) y = radius * numpy.sin(theta_grid) z = height_grid points_coordinates = numpy.stack([x.flatten(), y.flatten(), z.flatten()], axis=1) # (N_points, 3) # normals normals_x = numpy.cos(theta_grid) normals_y = numpy.sin(theta_grid) normals_z = numpy.zeros_like(normals_x) points_normals = numpy.stack([normals_x.flatten(), normals_y.flatten(), normals_z.flatten()], axis=1) # (N_points, 3) .. GENERATED FROM PYTHON SOURCE LINES 61-69 Define light source and view directions -------------------------------------------------------------------------------- Define the light source direction and observer position for the photometric rendering. For this example, we will use two light sources positioned at different locations. We also define the observer position and the objective is the render the appearance of the cylinder as seen from this position. .. GENERATED FROM PYTHON SOURCE LINES 69-77 .. code-block:: Python light_positions = numpy.array([ [1.0, 1.0, 0.0], [1.0, -1.0, 0.0] ]) # (N_light_sources, 3) observer_positions = numpy.array([5.0, 0.0, 0.0]) # (3,) .. GENERATED FROM PYTHON SOURCE LINES 78-88 Compute photometric properties using Bouguer law and Ward's BRDF model -------------------------------------------------------------------------------- Use the ``compute_bouguer_law`` and ``compute_brdf_ward`` functions to compute the photometric properties at the defined points on the cylinder surface. The first one is the ratio between irradiance :math:`E` at source intensity :math:`I`, the second one is the BRDF ratio between outgoing radiance :math:`L_o` and incoming irradiance :math:`E`, using 3 parameters: diffuse reflectance :math:`\rho_d`, specular reflectance :math:`\rho_s`, and surface roughness :math:`\sigma` (See the official documentation for more details). Assuming a given intensity for the light sources :math:`I = 1.0`, the image brightness is proportional to the incoming radiance :math:`L_o` on the camera sensor. .. GENERATED FROM PYTHON SOURCE LINES 88-117 .. code-block:: Python from pysdic import compute_bouguer_law, compute_brdf_ward bouger_law_ratio = compute_bouguer_law( surface_points=points_coordinates, surface_normals=points_normals, light_positions=light_positions, ) # (N_points, N_light_sources) print(f"Bouguer law ratio shape: {bouger_law_ratio.shape}, min: {bouger_law_ratio.min()}, max: {bouger_law_ratio.max()}") brdf_ward_values = compute_brdf_ward( surface_points=points_coordinates, surface_normals=points_normals, light_positions=light_positions, observer_positions=observer_positions, parameters = [0.1, 0.1, 0.5] # rho_d, rho_s, sigma ) # (N_points, N_light_sources, N_observers, N_models) # Here N_observers = 1 and N_models = 1, so we can squeeze these dimensions brdf_ward_values = brdf_ward_values[:, :, 0, 0] # (N_points, N_light_sources) print(f"BRDF Ward values shape: {brdf_ward_values.shape}, min: {brdf_ward_values.min()}, max: {brdf_ward_values.max()}") # Compute the radiance radiance = bouger_law_ratio * brdf_ward_values # (N_points, N_light_sources) # Sum the contributions from all light sources total_radiance = numpy.sum(radiance, axis=1) # (N_points,) print(f"Total radiance shape: {total_radiance.shape}, min: {total_radiance.min()}, max: {total_radiance.max()}") .. rst-class:: sphx-glr-script-out .. code-block:: none Bouguer law ratio shape: (100000, 2), min: 0.0, max: 5.822776397789505 /home/fdahe241/Programs/pysdic/docs/source/../../pysdic/core/photometric_operations.py:396: RuntimeWarning: divide by zero encountered in divide brdf = (rho_d / numpy.pi) + (rho_s / (4 * numpy.pi * sigma**2 * numpy.sqrt(cos_theta_i * cos_theta_0))) * \ /home/fdahe241/Programs/pysdic/docs/source/../../pysdic/core/photometric_operations.py:396: RuntimeWarning: invalid value encountered in multiply brdf = (rho_d / numpy.pi) + (rho_s / (4 * numpy.pi * sigma**2 * numpy.sqrt(cos_theta_i * cos_theta_0))) * \ BRDF Ward values shape: (100000, 2), min: 0.0, max: 0.07336558608523565 Total radiance shape: (100000,), min: 0.0, max: 0.318519420048296 .. GENERATED FROM PYTHON SOURCE LINES 118-123 Visualize the rendered photometric properties on the cylinder surface -------------------------------------------------------------------------------- Lets build a Point Cloud object to visualize the rendered photometric properties on the cylinder surface using pyvista. .. GENERATED FROM PYTHON SOURCE LINES 123-138 .. code-block:: Python from pysdic import PointCloud pc = PointCloud(points_coordinates) pc['radiance'] = total_radiance pc.visualize( property='radiance', property_cmap='plasma', point_size=5, camera_position=[10.0, 0.0, 0.0], camera_view_up=[0, 0, 1], camera_focal_point=[0, 0, 0], title="Photometric Rendering on Cylinder Surface" ) .. image-sg:: /_gallery/images/sphx_glr_example_photometric_rendering_on_cylinder_001.png :alt: example photometric rendering on cylinder :srcset: /_gallery/images/sphx_glr_example_photometric_rendering_on_cylinder_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.361 seconds) .. _sphx_glr_download_.._.._docs_source__gallery_example_photometric_rendering_on_cylinder.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_photometric_rendering_on_cylinder.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_photometric_rendering_on_cylinder.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_photometric_rendering_on_cylinder.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_